在lua中,函数是一种第一类值,它们具有特定的词法域。
第一类值表示在lua中函数与其他传统类型的值具有相同的权利。函数可以存储在变量中,全局变量或者拒不变量或者table中,可以作为实参传递给其他函数,还可以作为其他函数的返回值。
词法域是什么意思呢,这是指一个函数可以嵌套在另一个函数中。内部的函数可以访问外部函数中的变量。接下来就会看到,这项听似平凡的特性将给语言带来极大的能力。因为它允许在Lua中应用各种函数式语言中的强大编程技术。
在lua中有一个容易混淆的概念是,函数与所有其他值一样都是匿名的,即它们都没有名称。当讨论一个函数名时候,实际上是在讨论一个持有某函数的变量。这与其他变量持有各种值一个道理,可以以多种方式来操作这些变量。
a = {p = print}
a.p("Hello World")
print = math.sin
a.p(print(1))
sin = a.p
sin(10,20)
如果说函数式值得话,那是否可以说函数就是由一些表达式创建的呢,是的,事实上,在lua中最常见的是函数编写方式,例如:
function foo(x)
return 2*x
end
只是一种所谓的语法糖而已,也就是说,这只是以下代码的一种简化书写形式:
foo = function(x)
return 2*x
end
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)
像sort这样的函数,接受另一个函数作为实参,称其是一个高阶函数,高阶函数式一种强大的编程机制,应用匿名函数来创建高阶函数所需的实参则可以带来更大的灵活性。但请记住,高阶函数并没有什么特权。lua强调将函数视为第一类值,所以高阶函数只是一种居于该观点的应用体现而已。
为了进一步演示高阶函数的应用,将再写一个关于导数的高阶函数。在一个非形式化定义中,一个函数f在点x的导数就是(f(x+delta)-f(x))/delta,其中d趋向于无限小,可以用如下方式近似地计算这个函数f的导数:
function derivative(f,delta)
delta = delta or 1e-4
return function(x)
return (f(x+delta)-f(x))/delta
end
end
对于特定的函数f调用derivative(f)将近似地返回其导数,例如:
c = derivative(math.sin)
print(math.cos(10),c(10))
由于函数在lua中式一种第一类值,所以不仅可以讲其存储在全局变量中,还可以存储在局部变量甚至table的字段中。接下来还将看到,将函数存储在table的字段中可以支持许多Lua的高级应用。例如模块和面向对象编程!