函数是第一类值

简介: 函数是第一类值

Lua 语言中的函数是第一类值。以下的实例演示了第一类值的含义:

a = { p = print }     -- 'a.p' 指向'print'函数
a.p("Hello World")    --> Hello World
print = math.sin      -- 'print'现在指向sine函数
a.p(print(1))         --> 0.8414709848079
math.sin = a.p        -- 'sin'现在指向'print'函数
math.sin(10, 20)      --> 10    20


如果函数也是值的话,那么是否有创建函数的表达式呢?答案是肯定的。事实上, Lua 语言中常见的函数定义方式如下:

function foo (x) return 2*x end


就是所谓的语法糖的例子,它只是下面这种写法的一种美化方式:

foo = function (x) return 2*x end


赋值语句右边的表达式( function (x) body end )就是函数构造器,与表构造器 {} 类似。因此,函数定义实际上就是创建类型为 "function" 的值并把他赋值给一个变量的语句。


注意

Lua 语言中,所有的函数都是匿名的。像其他所有值一样,函数并没有名字。当讨论函数名时,比如 print ,实际上指的是保存该函数的变量。虽然我们通常会把函数赋值给全局变量,从而看似给函数起了一个名字,但在很多场景下仍然会保留函数的匿名性。


表标准库提供了函数 table.sort ,该函数以一个表为参数并对其中的元素排序。这种函数必须支持各种各样的排序方式:升序或降序、按数值排序或按字母顺序、按表中的键等。函数 sort 并没有试图穷尽所有的排序方式,而是提供了一个可选的参数,也就是所谓的排序函数,排序函数接收两个参数并根据第一个元素是否应排在第二个元素之前返回不同的值。例如,假设有一个如下所示的表:

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"},
}


如果想针对 name 字段、按字母顺序逆序对这个表排序,只需使用如下语句:

table.sort(network, function (a, b) return (a.name > b.name) end)


可见,匿名函数在这条语句中显示出了很好的便利性。


像函数 sort 这样以另一个函数为参数的函数,我们称之为高阶函数。高阶函数是一种强大的编程机制,而利用匿名函数作为参数正是其灵活性的主要来源。不过尽管如此,请记住高阶函数也没有什么特殊的,他们只是 Lua 语言将函数作为第一类值处理所带来结果的直接体现。


为了进一步演示高阶函数的用法,让我们来实现一个常见的高阶函数,即导数。按照通常的定义,函数 f 的导数为f^{'}=\frac{(f(x+\delta)-f(x))}{\delta}f=δ(f(x+δ)f(x)),其中 \deltaδ 趋向于无穷小。根据这个定义,可以用如下方式近似的计算导数:

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(5.2), c(5.2))      --> 0.46851667130038        0.46856084325086
print(math.cos(10), c(10))        --> -0.83907152907645       -0.8390443266
目录
相关文章
|
9月前
|
C语言
返回指针值
返回指针值
42 0
返回指针值
|
3月前
|
Python
怎样在函数中返回多个值?
怎样在函数中返回多个值?
110 52
|
4月前
|
存储 C语言 C++
如何通过指针作为函数参数来实现函数的返回多个值
在C语言中,可以通过将指针作为函数参数来实现函数返回多个值。调用函数时,传递变量的地址,函数内部通过修改指针所指向的内存来改变原变量的值,从而实现多值返回。
|
9月前
|
C++
C++程序返回指针值的函数
C++程序返回指针值的函数
74 1
|
9月前
|
JavaScript 前端开发
分享函数中 this 在不同场景下的指向与默认值,动态指定函数 this 值的方法
分享函数中 this 在不同场景下的指向与默认值,动态指定函数 this 值的方法
|
9月前
|
存储 C语言 索引
返回指针值的函数
返回指针值的函数
38 1
|
9月前
|
存储 弹性计算 运维
添加两个值
【4月更文挑战第29天】
48 4
|
9月前
|
存储 弹性计算 运维
添加多个值
【4月更文挑战第29天】
37 2
|
9月前
59.已知xxz+yzz=532,求所有可能的x,y,z的值
59.已知xxz+yzz=532,求所有可能的x,y,z的值
56 0
|
9月前
[题]写一个函数返回参数二进制中1的个数。
[题]写一个函数返回参数二进制中1的个数。
36 1