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」的主要内容,如果未能解决你的问题,请参考以下文章

Unity+Lua游戏开发的性能检测!

深入LUA脚本语言,让你彻底明白调试原理

HBase原理–所有Region切分的细节都在这里了

HBase原理–所有Region切分的细节都在这里了

HBase原理–所有Region切分的细节都在这里了

ulua 调用module函数