9.函数
9.1 知识点
函数的基本语法
命名函数语法
- 声明:
function 函数名()
-- 函数体
end
- 调用:
函数名()
匿名函数语法
- 声明:
装载函数的变量 = function()
-- 函数体
end
- 调用:
装载函数的变量()
函数是一等公民:可存变量、传参、返回。闭包、Upvalue 可以后面再了解。
无参数无返回值的函数
命名的无参数无返回值的函数
-- 命名的无参数无返回值的函数
-- F1() -- 不能在未声明函数前调用函数,否则会报错
function F1()
print("我是命名的无参数无返回值的函数F1")
end
F1() -- 我是命名的无参数无返回值的函数F1
匿名的无参数无返回值的函数
-- 匿名的无参数无返回值的函数
F2 = function()
print("我是匿名的无参数无返回值的函数F2")
end
-- 用 F2 装载了函数,有点类似 C# 中用一个变量保存委托
F2() -- 我是匿名的无参数无返回值的函数F2
有参数的函数
- 参数写在括号里,不用声明类型。
function F3(a)
print("我是有参数的函数F3")
print(a)
-- print("参数是" .. tostring(a)) -- 用 .. 拼接时,nil / boolean 最好先 tostring
end
-- 有参数的函数在括号中传入参数进行调用
F3(1) -- 1
F3("123") -- 123
F3(true) -- true
-- 如果传入的参数和函数参数个数不匹配
-- 不会报错,只会补 nil 或者丢弃多余参数
F3() -- nil
F3(nil) -- nil
F3(1, 2, 3) -- 1,后面的 2 和 3 被丢弃
和 C# 不同:参数个数不匹配不会报错,少传回补 nil,多传会丢弃。业务里要自己判断参数是否允许为空。
有返回值的函数
单返回值的函数
-- 单返回值的函数
-- 在函数体使用 return 返回变量
function F4(a)
print("我是单返回值的函数F4")
return a
end
-- 用一个变量接返回值
temp = F4(1)
print(temp) -- 1
多返回值的函数
-- 多返回值的函数
-- 在函数体使用 return 返回多个变量,变量间用逗号隔开
function F5(a)
print("我是多返回值的函数F5")
return a, "123", true
end
-- 用多个变量来接多个返回值,按位置一一对应
-- 如果变量不够,多出来的返回值会被丢弃
-- 如果变量多了,多出来的变量会被赋值 nil
temp1, temp2, temp3, temp4 = F5("1")
print(temp1) -- 1
print(temp2) -- 123
print(temp3) -- true
print(temp4) -- nil
函数的类型
- 装载函数的变量类型是
function。
F6 = function()
print("我是被查看函数类型的函数F6")
end
-- 使用 type 方法查看装载函数的变量类型
print(type(F6)) -- function
函数的重载
- Lua 不支持重载;同名后者覆盖前者。
-- 无参函数
function F7()
print("我是无参函数F7")
end
-- 有参函数,已经把上面的无参函数顶掉了
function F7(str)
print("我是有参函数F7")
print(str)
end
-- 尝试不传参数调用无参函数
-- 但无参函数已经被有参函数顶掉,所以调用的是后面的有参函数
F7() -- 我是有参函数F7 nil
变长参数
- 括号里写
...接收变长参数。
function F8(...)
-- 变长参数使用一个表存起来
local arg = { ... }
-- #arg 可以得到变长参数表的长度
print("我是变长参数F8,参数的长度是" .. #arg .. ",传进来的参数如下")
-- 再对表进行遍历输出
for i = 1, #arg do
print(arg[i])
end
end
F8(1, "123", true, 4, 5, 6) -- 1 "123" true 4 5 6
local arg = { ... },避免变长参数表污染全局。
函数嵌套
- 函数返回值也可以是函数。
函数返回命名函数
-- 函数返回命名函数
function F9()
local F99 = function()
print("我是F9函数内嵌套并返回出去的函数F99")
end
return F99
end
f9 = F9() -- F9() 调用后会返回一个函数,用 f9 作为装载函数的变量去接
f9() -- 我是F9函数内嵌套并返回出去的函数F99
函数返回匿名函数
-- 函数返回匿名函数
function F10()
return function()
print("我是F10函数内嵌套并返回出去的匿名函数")
end
end
f10 = F10() -- F10() 调用后会返回一个函数,用 f10 作为装载函数的变量去接
f10() -- 我是F10函数内嵌套并返回出去的匿名函数
函数可作返回值,有点像C#返回委托的感觉。
9.2 知识点代码
Lesson9_函数.lua
print("**********函数************")
print("**********知识点一 函数的基本语法************")
-- 命名函数语法:
-- 声明:
-- function 函数名()
-- 函数体
-- end
-- 调用:
-- 函数名()
-- 匿名函数语法:
-- 声明:
-- 装载函数的变量 = function()
-- 函数体
-- end
-- 调用:
-- 装载函数的变量()
print("**********知识点二 无参数无返回值的函数************")
-- 命名的无参数无返回值的函数
-- F1() -- 不能在未声明函数前调用函数,否则会报错
function F1()
print("我是命名的无参数无返回值的函数F1")
end
F1() -- 我是命名的无参数无返回值的函数F1
-- 匿名的无参数无返回值的函数
F2 = function()
print("我是匿名的无参数无返回值的函数F2")
end
-- 用 F2 装载了函数,有点类似 C# 中用一个变量保存委托
F2() -- 我是匿名的无参数无返回值的函数F2
print("**********知识点三 有参数的函数************")
-- 有参数的函数在函数括号中写入参数,不需要声明参数类型
function F3(a)
print("我是有参数的函数F3")
print(a)
-- print("参数是" .. tostring(a)) -- 用 .. 拼接时,nil / boolean 最好先 tostring
end
-- 有参数的函数在括号中传入参数进行调用
F3(1) -- 1
F3("123") -- 123
F3(true) -- true
-- 如果传入的参数和函数参数个数不匹配
-- 不会报错,只会补 nil 或者丢弃多余参数
F3() -- nil
F3(nil) -- nil
F3(1, 2, 3) -- 1,后面的 2 和 3 被丢弃
print("**********知识点四 有返回值的函数************")
-- 单返回值的函数
-- 在函数体使用 return 返回变量
function F4(a)
print("我是单返回值的函数F4")
return a
end
-- 用一个变量接返回值
temp = F4(1)
print(temp) -- 1
-- 多返回值的函数
-- 在函数体使用 return 返回多个变量,变量间用逗号隔开
function F5(a)
print("我是多返回值的函数F5")
return a, "123", true
end
-- 用多个变量来接多个返回值,按位置一一对应
-- 如果变量不够,多出来的返回值会被丢弃
-- 如果变量多了,多出来的变量会被赋值 nil
temp1, temp2, temp3, temp4 = F5("1")
print(temp1) -- 1
print(temp2) -- 123
print(temp3) -- true
print(temp4) -- nil
print("**********知识点五 函数的类型************")
-- 装载函数的变量类型是 function
F6 = function()
print("我是被查看函数类型的函数F6")
end
-- 使用 type 方法查看装载函数的变量类型
print(type(F6)) -- function
print("**********知识点六 函数的重载************")
-- Lua 中的函数不支持重载
-- 同名函数会被最后一个声明的同名函数顶掉
-- 调用时默认调用最后声明的那个函数
-- 无参函数
function F7()
print("我是无参函数F7")
end
-- 有参函数,已经把上面的无参函数顶掉了
function F7(str)
print("我是有参函数F7")
print(str)
end
-- 尝试不传参数调用无参函数
-- 但无参函数已经被有参函数顶掉,所以调用的是后面的有参函数
F7() -- 我是有参函数F7 nil
print("**********知识点七 变长参数************")
-- 在函数括号中写入 ...
function F8(...)
-- 变长参数使用一个表存起来
local arg = { ... }
-- #arg 可以得到变长参数表的长度
print("我是变长参数F8,参数的长度是" .. #arg .. ",传进来的参数如下")
-- 再对表进行遍历输出
for i = 1, #arg do
print(arg[i])
end
end
F8(1, "123", true, 4, 5, 6) -- 1 "123" true 4 5 6
print("**********知识点八 函数嵌套************")
-- 函数的返回值也可以是函数类型的变量
-- 函数返回命名函数
function F9()
local F99 = function()
print("我是F9函数内嵌套并返回出去的函数F99")
end
return F99
end
f9 = F9() -- F9() 调用后会返回一个函数,用 f9 作为装载函数的变量去接
f9() -- 我是F9函数内嵌套并返回出去的函数F99
-- 函数返回匿名函数
function F10()
return function()
print("我是F10函数内嵌套并返回出去的匿名函数")
end
end
f10 = F10() -- F10() 调用后会返回一个函数,用 f10 作为装载函数的变量去接
f10() -- 我是F10函数内嵌套并返回出去的匿名函数
-- 函数返回函数这个写法很常见
-- 这里先只理解“函数可以被当成值返回”即可
-- 闭包、Upvalue、外部变量捕获这些机制
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com