7.1 函数定义 基本语法 1 2 3 4 5 6 7 8 9 10 11 12 13 function add (a, b) return a + b end local subtract = function (a, b) return a - b end print (add(3 , 4 )) print (subtract(10 , 3 ))
语法糖 当函数存储在表中时,可以使用冒号语法:
1 2 3 4 5 6 7 8 9 10 11 12 local obj = {}obj.greet = function (self, name) print ("Hello, " .. name .. "!" ) end obj.greet(obj, "Lua" ) function obj:greet (name) print ("Hello, " .. name .. "!" ) end obj:greet("Lua" )
7.2 参数传递 形参与实参 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 function print_info (name, age, city) print ("姓名:" .. name) print ("年龄:" .. age) print ("城市:" .. city) end print_info("张三" , 25 , "北京" ) print_info("李四" , 30 ) print_info("王五" , 28 , "上海" , "额外参数" )
参数默认值 Lua 不支持默认参数,但可以用 or 运算符实现:
1 2 3 4 5 6 7 8 9 function greet (name, greeting) name = name or "访客" greeting = greeting or "你好" print (greeting .. "," .. name) end greet() greet("张三" ) greet("李四" , "Hello" )
参数类型检查 1 2 3 4 5 6 function divide (a, b) assert (type (a) == "number" , "a 必须是数字" ) assert (type (b) == "number" , "b 必须是数字" ) assert (b ~= 0 , "除数不能为 0" ) return a / b end
7.3 返回值 单一返回值 1 2 3 4 5 6 function square (n) return n * n end local result = square(5 )print (result)
多返回值 这是 Lua 函数的一个重要特性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 function min_max (a, b, c) local min = math .min (a, b, c) local max = math .max (a, b, c) return min , max end local min_val, max_val = min_max(3 , 7 , 1 )print (min_val, max_val) local _, max_val = min_max(3 , 7 , 1 )print (max_val) local result = min_max(3 , 7 , 1 )print (result)
table.unpack 与多返回值1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 local function get_user () return "张三" , 25 , "北京" end local info = {get_user()}print (info[1 ], info[2 ], info[3 ]) local function combine (...) return ... end local data = {"a" , "b" , "c" }print (combine(table .unpack (data)))
7.4 变长参数 ... 变长参数允许函数接受任意数量的参数:
基本用法 1 2 3 4 5 6 7 8 9 10 11 function sum (...) local total = 0 for i = 1 , select ("#" , ...) do total = total + select (i, ...) end return total end print (sum(1 , 2 , 3 )) print (sum(1 , 2 , 3 , 4 , 5 )) print (sum())
用 {...} 收集参数 1 2 3 4 5 6 7 8 9 10 11 12 function print_all (...) local args = {...} for i, v in ipairs (args) do print (i, v) end end print_all("a" , "b" , "c" )
使用 select() select() 用于访问变长参数而无需创建表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function sum (...) local total = 0 for i = 1 , select ("#" , ...) do total = total + select (i, ...) end return total end local first, second = select (1 , "a" , "b" , "c" )print (first, second) local remaining = select (3 , "a" , "b" , "c" )print (remaining)
混合参数 普通参数在前,变长参数在后:
1 2 3 4 5 6 7 8 function printf (fmt, ...) local args = {...} print (string .format (fmt, table .unpack (args))) end printf("姓名:%s,年龄:%d" , "张三" , 25 )
7.5 具名参数 Lua 不支持 Python 风格的命名参数,但可以用 table 模拟:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 function create_user (params) local name = params.name or "匿名" local age = params.age or 18 local city = params.city or "未知" local email = params.email or "" return { name = name, age = age, city = city, email = email } end local user1 = create_user({name = "张三" , age = 25 })local user2 = create_user({name = "李四" , email = "li@example.com" })local user3 = create_user{name = "王五" , city = "深圳" }
7.6 函数是第一类值 函数可以像其他值一样被赋值、传递、存储:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 local func = function (x) return x * 2 end print (func(5 )) local operations = { add = function (a, b) return a + b end , sub = function (a, b) return a - b end , mul = function (a, b) return a * b end , } print (operations.add(3 , 4 )) print (operations.mul(3 , 4 )) function apply_to_array (arr, func) local result = {} for i, v in ipairs (arr) do result[i] = func(v) end return result end local numbers = {1 , 2 , 3 , 4 , 5 }local doubled = apply_to_array(numbers, function (x) return x * 2 end )function create_multiplier (factor) return function (x) return x * factor end end local double = create_multiplier(2 )local triple = create_multiplier(3 )print (double(5 )) print (triple(5 ))
7.7 常用函数模式 回调函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 function fetch_data (callback) print ("开始获取数据..." ) local data = {id = 1 , name = "测试数据" } if callback then callback(data) end end fetch_data(function (data) print ("收到数据:" .. data.name) end )
排序比较器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 local people = { {name = "张三" , age = 25 }, {name = "李四" , age = 30 }, {name = "王五" , age = 20 }, } table .sort (people, function (a, b) return a.age < b.age end )table .sort (people, function (a, b) return a.name > b.name end )
工厂函数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function create_counter (start, step) start = start or 0 step = step or 1 local count = start return { next = function () local current = count count = count + step return current end , reset = function () count = start end , value = function () return count end } end local counter = create_counter(10 , 2 )print (counter.next ()) print (counter.next ()) print (counter.next ()) counter.reset() print (counter.next ())
7.8 本章小结
函数用 function 定义,可以具名或匿名
参数不足时为 nil,多余参数被忽略
支持多返回值,用逗号分隔
变长参数 ... 配合 {...} 或 select() 使用
可以用 table 模拟具名参数
函数是第一类值,可作为参数和返回值
练习题
实现一个 range(start, end, step) 函数,返回一个包含指定范围内所有数字的数组
实现 max(...) 函数,返回任意数量数字中的最大值
用 table 参数实现一个配置化函数 create_window({title, width, height, resizable})
写一个 compose(f, g) 函数,返回两个函数的复合函数 f(g(x))
实现一个 partial(func, ...) 函数,支持函数柯里化(部分应用)