Lua函数-你可能没有留意的细节都在这里「DaemonCoder」
Posted DaemonCoder
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Lua函数-你可能没有留意的细节都在这里「DaemonCoder」相关的知识,希望对你有一定的参考价值。
函数的定义
函数定义的写法如下:
local function func_name(arg1, arg2, ...)
-- statements
return arg1, arg2, ...
end
local 指定函数的作用域为局部,不加local表示全局函数。function是关键字,表示声明的是一个函数,func_name自定义的函数名,函数名字可以省略,表示定义的是一个匿名函数(后面可以看到匿名函数的用法)。arg1, arg2为指定函数需要的参数,return指定函数返回。
下面看一个示例:
local function sum(a, b)
return a + b
end
print(sum(2, 3)) -- 5
Lua函数支持多值返回:
local function get_msg()
return "Hello", true -- 返回多个值
end
local msg, err = get_msg() -- 接收返回的多个值
print(msg, err) -- Hello true
函数变量
在之前的文章 Lua 数据类型 中我们提到,Lua的函数和数值、字符串等一样,是一种类型,这就意味着我们可以创建一个值为函数的变量,先看一个示例:
local function sum(a, b)
return a + b
end
print(sum(2, 3)) -- 5
local sub = function(a, b)
return a - b
end
print(sub(8, 5)) -- 3
local math = {
add = sum,
sub = sub,
}
print(math.add(5, 3)) -- 8
print(math.sub(5, 3)) -- 2
通过个这个示例可以看到:
sum 是用之前介绍的常规方式定义的函数。
sub 是一个变量,值是一个匿名函数,则可以像函数调用的方式来调用 sub 变量。
math 是自定义的一个表,有两个字段 add、sub,这两个字段的值都是函数类型,所以也可以对其进行函数调用:math.add()、math.sub()。
函数传参
Lua的函数,不要求传入的实参个数和形参个数一致。实参个数大于形参个数时,多传入的实参被忽略;实参个数小于形参个数时,不足的参数在函数体中的值为 nil 。
function say(a, b)
print(a, b == nil)
end
say('www.daemoncoder.com') -- www.daemoncoder.com true
say('daemon', 'coder', '.com') -- daemon false
函数参数的值传递、引用传递情况,在和Lua变量的赋值表现是一样的。函数体内如果修改传入参数的值,是否会对调用函数处的值产生影响,不同的类型表现不一致,数值、字符串等不会产生影响,但是修改传入一个表内的字段值时会对原有表产生影响。具体示例可以参考之前的文章 Lua赋值。
默认参数
在C++中,函数参数可以设置默认值,当传入的实参数不足时,就是指定的默认值,写法如下:
#include <stdio.h>
void default_value(int a, int b = 2) { // b参数设置默认值为2
printf("a = %d, b = %d\n", a, b);
}
int main() {
default_value(1); // 输出:a = 1, b = 2
return 0;
}
对不起,Lua不支持默认参数的写法!这种写法在Lua中会直接语法不通过。
函数重载
熟悉Java的朋友,在很多情况下会用到方法重载,即定义两个名字相同的方法,传入的参数个数或类型不同,根据参数来决定具体是用的哪个方法,示例如下:
package test;
public class Test {
public static void main(String[] args) {
System.out.println(add(1, 2)); // 3
System.out.println(add("daemoncoder", ".com")); // daemoncoder.com
}
public static int add(int a, int b) {
return a + b;
}
public static String add(String a, String b) {
return a + b;
}
}
如果你也希望Lua函数也支持这样的写法,那可能又要你失望了。对不起,Lua不支持函数重载!但是这种写法不会报错,看下面Lua示例:
function overload(a, b)
print("In first function", a, b)
end
function overload(a, b, c)
print("In second function", a, b, c == nil)
end
overload(1, 2) -- In second function 1 2 true
定义了两个都叫 overload 的方法,参数个数不同,来达到Java世界里的重载效果,最后调用处传入和第一个定义相匹配的参数,运行后发现其实调用的是第二个方法,参数c是nil。
Lua中定义两个相同名字的函数,没有重载一说,其实是函数的重定义,第二个函数会把第一个覆盖掉,第一个函数定义没有意义。
可变参数列表
Lua是支持可变参数列表的,在函数的最后一个参数定义处用 ... 表示,函数体中 ... 会当作一个表处理,示例如下:
function add(...)
local s = 0
local args = {...}
for _, v in ipairs(args) do -- {...} 表示一个由所有变长参数构成的数组
s = s + v
end
return s
end
print(add(1, 2, 3, 4)) -- 10
函数声明与调用顺序
函数需要先声明才能调用,先看示例:
function jump()
run()
print("jump")
end
-- jump(); -- 会报错:attempt to call a nil value (global 'run')
function run()
print("run")
end
jump(); -- OK
第一处被注释的 jump() 处,不能调用 jump(),因为jump方法体中调用了 run(),此时还没有执行到 run 函数的定义处(即:run值为nil),会报错:attempt to call a nil value (global 'run')。
最后调用的 jump() 处,此时 run 函数已经定义过了,所以不会报错,也可以把 run() 放到 jump() 之前,这样就可以在被注释的地方正常调用了。
转载请注明出处,本文原始链接:https://www.daemoncoder.com/a/Lua%E5%87%BD%E6%95%B0/4d546b3d
点击下方阅读原文,或访问 daemoncoder.com 发现更多优质内容。
扫码关注公共号,第一时间收到优质内容
以上是关于Lua函数-你可能没有留意的细节都在这里「DaemonCoder」的主要内容,如果未能解决你的问题,请参考以下文章