返回首页

教程导航

返回首页

🏷️ 标签(1)

🗂️ 分类(1)

第 6 章 函数

第 6 章 函数

函数是 Lua 的一等值,可以赋值给变量、传给其他函数,也可以作为返回值。函数与闭包是 Lua 设计中最有表达力的部分之一。

定义与调用函数

local function add(a, b)
  return a + b
end

print(add(2, 3))

函数也可以使用匿名函数表达式:

local multiply = function(a, b)
  return a * b
end

print(multiply(4, 5))

调用函数时参数不足会补 nil,参数过多会被忽略:

local function show(a, b)
  print(a, b)
end

show(1)
show(1, 2, 3)

多返回值

Lua 函数可以返回多个值:

local function minMax(values)
  local minValue = math.huge
  local maxValue = -math.huge

  for _, value in ipairs(values) do
    minValue = math.min(minValue, value)
    maxValue = math.max(maxValue, value)
  end

  return minValue, maxValue
end

local minimum, maximum = minMax({ 4, 2, 9, 1 })
print(minimum, maximum)

多返回值只在调用表达式处于允许的位置时全部保留。放入表时需要额外处理:

local function values()
  return 1, 2, 3
end

local first = { values() }
local second = { values(), 4 }

print(#first)  -- 3
print(#second) -- 2

可变参数

使用 ... 接收任意数量参数:

local function sum(...)
  local total = 0
  for _, value in ipairs({ ... }) do
    total = total + value
  end
  return total
end

也可以使用 select:

local function inspect(...)
  print("数量:", select("#", ...))
  for index = 1, select("#", ...) do
    print(index, select(index, ...))
  end
end

inspect("a", "b", "c")

转发参数

local function log(level, ...)
  io.write("[" .. level .. "] ")
  print(...)
end

log("INFO", "server", "started")

作用域与闭包

函数可以捕获外部局部变量,即使定义它的函数已经返回:

local function makeCounter()
  local count = 0

  return function()
    count = count + 1
    return count
  end
end

local nextNumber = makeCounter()
print(nextNumber()) -- 1
print(nextNumber()) -- 2

每个闭包实例拥有独立的环境。多个闭包可以共享同一组变量:

local function makeAccount(initial)
  local balance = initial

  return {
    deposit = function(amount)
      balance = balance + amount
      return balance
    end,
    withdraw = function(amount)
      if amount > balance then
        return nil, "余额不足"
      end
      balance = balance - amount
      return balance
    end
  }
end

这种模式可以在不使用元表的情况下实现简单封装。

函数式编程基础

高阶函数

local function map(values, transform)
  local result = {}
  for index, value in ipairs(values) do
    result[index] = transform(value)
  end
  return result
end

local doubled = map({ 1, 2, 3 }, function(value)
  return value * 2
end)

过滤与归约

local function filter(values, predicate)
  local result = {}
  for _, value in ipairs(values) do
    if predicate(value) then
      result[#result + 1] = value
    end
  end
  return result
end

local function reduce(values, initial, combine)
  local accumulator = initial
  for _, value in ipairs(values) do
    accumulator = combine(accumulator, value)
  end
  return accumulator
end

函数式写法能减少临时状态,但不要把简单循环强行改写成多层高阶函数。选择团队最容易理解的表达方式。

上一章:控制流 | 下一章:表