第六章: 再论函数
Lua 中的函数是带有词法定界(lexical scoping)的第一类值(first-class values)。
第一类值指:在 Lua 中函数和其他值(数值、字符串)一样,函数可以被存放在变
量中,也可以存放在表中,可以作为函数的参数,还可以作为函数的返回值。
词法定界指:被嵌套的函数可以访问他外部函数中的变量。这一特性给 Lua 提供了
强大的编程能力。
先给出一些实例,看看lua的函数是如何跟普通变量一样可以进行赋值 作为参数。。。
function foo(x) return x * 2 end print(foo(3)) -- 6 a = {p = print} a.p("hello world") -- hello world print = math.sin -- print new refer to the sin function a.p(print(1)) sin = a.p sin(10,20) -- 10 20 funciton print network = { {name = "grauna", IP = "210.26.30.34"}, {name = "arraial", IP = "210.26.30.23"}, {name = "lua", IP = "210.26.23.12"}, {name = "derain", IP = "210.26.23.20"}, } table.sort( network, function (a,b) return (a.name > b.name) end) --没有名字的函数 匿名函数
1 闭包
当一个函数内部嵌套另一个函数时,内部的函数体可以访问外部的函数的局部变量,这种特征叫做词法界定。
names = {"Peter","Paul","Mary"} grades={Mary=10,Paul=7,Mary=5} table.sort(names,function (n1,n2) return grades[n1] > grades[n2] end) --实现上述功能函数 function sortBygrade(names,grades) table.sort(names,function (n1,n2) return grades[n1] > grades[n2] -- compare the grades end) end
一个计数器的例子:
function newCounter() local i = 0 return function () i = i + 1 return i end end c1 = newCounter() print(c1()) --1 print(c1()) --2 c2 = newCounter() print(c2()) --1 print(c1()) –3
技术上来讲, 闭包指值而不是指函数,函数仅仅是闭包一个原型声明;尽管如此
也可以使用闭包来实现函数重定义:
print(math.sin(100)) oldSin = math.sin math.sin = function (x) return oldSin(x * math.pi / 180) end print(math.sin(100))
2、非全局函数
Lua的函数可以作为全局变量也可以作为局部变量,函数使用table作用域, 有三种定义方式
-- 表和函数放在一起 Lib = {} Lib.foo = function (x,y) return x + y end Lib.goo = function(x,y) return x - y end -- 使用表构造函数 Lib2 = { foo = function(x,y) return x + y end, goo = function(x,y) return x - y end } --定义方式三 function Lib.square(x) return 2 * x end function Lib.sqrt(x) return math.sqrt(x) end print(Lib.foo(2,3)) print(Lib2.goo(4,5)) print(Lib.square(2)) print(Lib.sqrt(3))
3、正确的尾调用
Lua函数的另外一个有趣的特征是可以正确的处理尾调用(proper tail recursion)
尾调用是一种类似在函数结尾的goto调用,当函数最后一个动作是调用另外一个函数时,我们称这种调用为尾调用。
例如:
function f(x) return g(x) end
时间: 2024-10-18 18:55:54