Lua 函数调用时, 需要带括号(对于单个参数的函数,某些值不需要用括号, 如字符串, 表).
但是注意return是可以带括号也可以不带括号的.
这里重点说到括号, 因为括号和返回多值的函数关系很大, 也就是"诡异"的地方, 后面会举例.
函数可以作为一个语句执行, 那有点类似一个过程语言, 执行完的函数结果被抛弃掉.
例如 :
print("abc") -- 这作为一个语句执行.
函数也可以在一个表达式中执行, 那么结果会被返回, 对于多值函数需要注意返回的值的个数.
例如 :
i = math.sin(123) -- 这里的math.sin函数在表达式中, 所以结果返回.
函数调用必须带括号, 除了单个参数的函数, 并且参数类型为字符串, 表构造器时, 可以不带括号.
例如:
函数的结构
> print {1,2,3}
table: 0x9465c0
> print [====[
>> hellp
>> nihao
>> ]]
>> ]====]
hellp
nihao
]]
> print "hello"
hello
> print {}
table: 0x946d10
函数的结构
包含函数名, 参数, 函数体几个部分.
例如 :
function add(a)
local sum = 0
for i = 1, #a do
sum = sum + a[i]
end
return sum
end
函数的参数, 和本地变量类似, 调用函数时为值传递的方式. 在函数中修改这个变量对传入的变量没有影响.
同时, 函数调用时允许传入的参数个数和函数定义的个数不一致的情况.
例如
可以这么调用 :
如果函数参数缺失的情况下, 可以给它默认值, 我现在还不清楚是不是可以在函数定义时指定, 如果不能的话就这么这么搞了.
function f (a,b)
print(a,b)
end
可以这么调用 :
> function f(a,b)
>> print(a,b)
>> end
> f() -- a,b都为nil
nil nil
> f(1) -- a=1, b=nil
1 nil
> f(2)
2 nil
> f(1,2,3) -- a=1, b=2, 3抛弃
1 2
> f(1,2)
1 2
如果函数参数缺失的情况下, 可以给它默认值, 我现在还不清楚是不是可以在函数定义时指定, 如果不能的话就这么这么搞了.
function f(a,b)
if a == nil then a = 1 end
if b == nil then b = 1 end
print(a,b)
end
为什么不用 a= a or 1呢? 因为当传入的是boolean值时, false的话, false or 1也变1了.
这个是Lua的一种逻辑判断值的取值问题. 例如
Lua支持一个函数返回多个值, 但是返回多个值时, 有多少个值传递, 或者被抛弃, 和用法有关, 比较诡异的地方来了.
在赋值时也一样
还有一种情况, 如果要强制使用仅仅返回1个结果的话, 在函数外加括号就可以. 这就是文章开头提到的括号用法.
多值函数例子 :
比较容易记住Lua的多值返回函数的诡异的例子 :
a or b -- 当a = nil或false时, a or b这个逻辑判断表达式的值就是b, 当a不为false或者nil时, 那么这个表达式的值就是a.
> print(false or 1)
1
> print(0 or false)
0
> print(0 or "hello")
0
> print(nil or "hello")
hello
> print(false or "hello")
hello
a and b 则当a为真(不为false或nil)时, 表达式的结果等于b, 如果a为真, 则表达式的结果为a.
> print(1 and false)
false
> print(1 and nil)
nil
> print(1 and 2)
2
> print(false and "hello")
false
> print(nil and "hello")
nil
Lua支持一个函数返回多个值, 但是返回多个值时, 有多少个值传递, 或者被抛弃, 和用法有关, 比较诡异的地方来了.
> print(string.find("hello","llo"))
3 5
string.find("hello","llo")函数返回2个值, 第一个值为匹配到的字符串的开始位置, 第二个值为结束位置.
但是, 当多值函数后面再有表达式时, 多值函数就只返回第一个值, 后面的值被抛弃.
> print(string.find("hello","llo"), "hell") -- 这样的话string.find("hello","llo")只返回了第一个结果3. 5被抛弃了.
3 hell
在赋值时也一样
> a,b = string.find("hello","llo")
> print(a,b)
3 5
> a,b = string.find("hello","llo"), "he"
> print(a,b)
3 he
还有一种情况, 如果要强制使用仅仅返回1个结果的话, 在函数外加括号就可以. 这就是文章开头提到的括号用法.
> a=(string.find("hello","llo"))
> print(a)
3
> a=string.find("hello","llo")
> print(a)
3
> print(string.find("hello","llo"))
3 5
> print((string.find("hello","llo"))) -- 多值函数用括号包一层, 返回第一个结果值. 而不是整个list
3
多值函数例子 :
> function max(a)
local mi = 1 -- index
local m = a[mi]
for i=1,#a do
if a[i] > m then
mi = i; m = a[i]
end
end
return m, mi
end
> print(max({1,2,3,4,5}))
5 5
> print(max({1,2,3,4,5,100}))
100 6
比较容易记住Lua的多值返回函数的诡异的例子 :
> function foo0() end
> function foo1() return "a" end
> function foo2() return "a", "b" end
> x,y = foo2()
> print(x,y)
a b
> x = foo2()
> print(x)
a
> x,y,z = 10,foo2() -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值. 没有值的话, 全取.
> print(x,y,z)
10 a b
> x,y = foo0()
> print(x,y)
nil nil
> x,y = foo1()
> print(x,y)
a nil
> x,y,z = foo2()
> print(x,y,z)
a b nil
> x,y = foo2(), "hello" -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值.
> print(x,y)
a hello
> x,y = foo0(), "hello", "nihao"
> print(x,y)
nil hello
> t = {foo0(), foo2(), 4} -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值.
> print(t)
table: 0x9515c0
> for i = 1,#t do
>> print(t[i])
>> i = i+1
>> end
nil
a
4
> t = {foo0(), foo2()}
> for i = 1,#t do
print(t[i])
i = i+1
end
nil
a
b
> print(foo2(),1) -- 在这里, 也要注意, 后面有值的情况下, 多值函数都只取一个值.
a 1
> print(foo2())
a b