Lua 函数用法和它的"诡异"之处

简介:
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的一种逻辑判断值的取值问题. 例如
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

目录
相关文章
|
6月前
|
存储 C语言 图形学
C 函数中如何保存 Lua 的数据(1)
C 函数中如何保存 Lua 的数据(1)
93 0
|
存储 Java C语言
lua变量、数据类型、if判断条件和数据结构table以及【lua 函数】
lua变量、数据类型、if判断条件和数据结构table以及【lua 函数】
99 0
|
1月前
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
Lua的面向对象编程、协同线程与协同函数的概念和使用,以及Lua文件I/O操作的基本方法。
32 4
lua面向对象(类)和lua协同线程与协同函数、Lua文件I/O
|
1月前
|
数据可视化 开发者 索引
详解Wireshark LUA插件函数:function p_myproto.dissector(buffer, pinfo, tree)
在 Wireshark 中,LUA 插件通过 `function p_myproto.dissector(buffer, pinfo, tree)` 扩展协议解析能力,解析自定义应用层协议。参数 `buffer` 是 `PacketBuffer` 类型,表示原始数据包内容;`pinfo` 是 `ProtoInfo` 类型,包含数据包元信息(如 IP 地址、协议类型等);`tree` 是
68 1
|
6月前
|
C语言 C++ 索引
C 函数中如何保存 Lua 的数据(2)
C 函数中如何保存 Lua 的数据(2)
79 1
[✔️]lua中的module函数
[✔️]lua中的module函数
206 0
|
XML Java 数据格式
【Lua基础 第4章】Lua的流程控制、#的作用、table的创建方式、table表常用方法、函数、多返回值、可变长参数
Lua的流程控制、#的作用、table的创建方式、table表常用方法、函数、多返回值、可变长参数
148 0
【Lua基础 第4章】Lua的流程控制、#的作用、table的创建方式、table表常用方法、函数、多返回值、可变长参数
|
数据采集 大数据 开发者
Lua 语法函数|学习笔记
快速学习 Lua 语法函数
Lua 语法函数|学习笔记
lua语言——特殊用法
lua语言——特殊用法
254 0
下一篇
无影云桌面