作为值的函数
存储并传递函数。
作为值的函数 是 CoddyKit 上的免费 Lua Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Lua Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Lua Academy 课程共包含 4 节课。
函数是一等公民
在 Lua 中,函数是一等值。这意味着函数就是一种数据:您可以将它存储在变量中,将它传递给另一个函数,返回它,或将它保存到表中。
这一理念支撑着整个函数式编程。将函数视为数字或字符串后,您就可以构建灵活且可复用的工具。
将函数存储在变量中
您为函数指定的名称实际上只是一个保存函数值的变量。您可以自由地将这个值赋给另一个变量。
下面的两个名称都指向同一个底层函数,因此调用任意一个名称都会运行相同的代码。
local function greet(name)
return "Hello, " .. name
end
local hi = greet
print(greet("Ada"))
print(hi("Lin"))匿名函数
创建函数并不需要名称。匿名函数使用 function ... end 语法编写,并直接作为一个值使用。
将匿名函数赋给局部变量,与普通的函数定义效果相同,只是写在了使用位置。
local square = function(x)
return x * x
end
print(square(5))
print(square(9))将函数作为参数
由于函数也是值,您可以将它们传入其他函数。接收另一个函数的函数称为高阶函数。
这里的 apply 在您传给它一个要运行的函数之前,并不知道要执行什么工作。
local function apply(f, x)
return f(x)
end
local function double(n) return n * 2 end
print(apply(double, 10))
print(apply(function(n) return n + 1 end, 10))返回一个函数
函数可以返回另一个函数。这样,您就能根据传入的参数按需构建函数。
下面的 multiplier 每次都会构建一个全新的函数,并记住您提供的因子。
local function multiplier(factor)
return function(x)
return x * factor
end
end
local triple = multiplier(3)
print(triple(4))
print(multiplier(10)(5))闭包捕获变量
当返回的函数使用外层函数中的局部变量时,它就会捕获该变量。函数与其捕获的变量组合在一起,称为闭包。
只要闭包存在,被捕获的 factor 就会持续存在,即使外层调用已经结束。
local function counter()
local n = 0
return function()
n = n + 1
return n
end
end
local next = counter()
print(next())
print(next())
print(next())表中的函数
表可以像保存其他值一样保存函数。Lua 正是通过这种方式构建模块和对象的:表将名称映射到函数值。
您可以通过键查找函数并调用它,甚至可以遍历一个保存各种操作的表。
local ops = {
add = function(a, b) return a + b end,
sub = function(a, b) return a - b end
}
print(ops.add(2, 3))
print(ops["sub"](9, 4))策略表
将函数存储在表中后,就可以在运行时通过键选择行为。这可以用简洁的查找替代冗长的 if-else 链。
按名称选择操作可以让调用代码保持简短,并且便于通过新增键来扩展。
local dispatch = {
upper = string.upper,
lower = string.lower,
rev = string.reverse
}
local function run(name, s)
return dispatch[name](s)
end
print(run("upper", "lua"))
print(run("rev", "lua"))回调函数
回调函数是您传入、以便稍后调用的函数。Lua 的标准库使用了这种模式,例如 table.sort 接收一个比较函数。
回调函数决定规则,库负责循环和重新排列。
local nums = {5, 2, 9, 1}
table.sort(nums, function(a, b)
return a > b
end)
print(table.concat(nums, ", "))函数具有独立身份
每个函数值都是一个独立的对象。两个分别创建的函数字面量永远不相等,即使其中包含相同的代码。
但是,存储在两个变量中的同一个函数会比较为相等,因为两个名称引用的是同一个值。
local f = function() return 1 end
local g = function() return 1 end
local h = f
print(f == g)
print(f == h)这为什么重要
将函数视为值后,您就能只编写一次通用工具,再通过传入不同的函数对其进行定制。映射、过滤、部分应用和组合都依赖于这一点。
本课程的后续内容将在一等函数和闭包的基础上构建实用模式。
快速检查
测试您对 Lua 一等函数的理解。
回顾
Lua 中的函数是一等值:您可以将它们存储在变量和表中,将它们作为参数传递,也可以从其他函数中返回它们。
返回一个捕获外层局部变量的函数,就会创建闭包。这些理念是后续所有函数式模式的基础。
常见问题解答
「作为值的函数」课时是免费的吗?
是的 — 「作为值的函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Lua Academy 课程的其余内容,请升级到 CoddyKit PRO。 Lua Academy 课程共包含 4 节课。
「作为值的函数」这节课中我会学到什么?
存储并传递函数。 你通过在浏览器中直接运行的动手代码来练习 Lua Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Lua Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Lua Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「作为值的函数」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Lua Academy 课中编写并运行代码吗?
能。每节 Lua Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。