<< ..
Scala中的高阶函数 lambda函数
发布时间:前菜1: 什么是高阶函数
wiki中定义
在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数:
- 接受一个或多个函数作为输入
- 输出一个函数
通俗些理解就是一个函数可以把另一个函数作为参数传参,函数可以作为变量传递。从一段简单的python代码构建一个高阶函数体验一下,python内建的abs()
取绝对值函数作为参数传递进add()
中变成了f()
:
>>> def add(x, y, f):
... return f(x) + f(y)
...
>>> add(-5, 9, abs)
14
前菜2: 什么是lambda函数
网上有人说,在实用界就是匿名函数,在需要一个函数,但是又不想费神去命名一个函数的场合下使用(知乎)。举个实例,同样是求平方根, 因为后者多定义了一个(污染环境的)函数,尤其如果这个函数只会使用一次的话。而且第一种写法实际上更易读,因为那个映射到列表上的函数具体是要做什么,非常一目了然。如果你仔细观察自己的代码,会发现这种场景其实很常见:你在某处就真的只需要一个能做一件事情的函数而已,连它叫什么名字都无关紧要。Lambda 表达式就可以用来做这件事。
>>> map( lambda x: x*x, [y for y in range(10)] )
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
>>>
>>> def sq(x):
... return x * x
...
>>> map(sq, [y for y in range(10)])
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>>
scala中的高阶函数
// 普通函数
scala> def foo(s: String) = { println(s) }
foo: (s: String)Unit
// 高阶函数
scala> def hf(f: String => Unit) = f("higher")
hf: (f: String => Unit)Unit
// 把普通函数赋值给变量f
scala> val f:String=>Unit = foo
f: String => Unit = <function1>
// 上面的函数类型String=>Unit 也可以写为Function1[String,Unit]
scala> val f:Function1[String,Unit] = foo
// 把变量 f 当作参数传递给高级函数hf
scala> hf(f)
higher
scala中的lambdda形式
承接上面的用法,使用lambda表达式 (s:String) => println(s)
作为匿名函数传入hf()
scala> hf((s: String) => println(s))
简化lambda
scala> def hf(f: String => Unit) = f("higher")
// 省略了s的类型,这是因为在定义hf时已经声明了参数类型为String=>Unit,编译器会把lambda表达式中的入参和出参按声明的类型来对待
scala> hf(s=>println(s)) // 第1个简化版本
higher
// 采用了占位符的方式。它的形式为,对于所有的 x=>g(x) 都可以用占位符的形式写为:g(_),相当于省去了lambda表达式的入参和箭头部分,然后用占位符表示入参
scala> hf(println(_)) // 第2个简化版本
higher
scala> hf(println _) // 第3个简化版本
higher
// 第4个版本的背后其实是编译器支持lambda的“eta转换”(hongjiang.info scala中的eta-conversion)。
// 简单的说就是对于lambda表达式中只有一个参数,并且箭头右边的逻辑是对入参执行一个函数:即 x => f(x)
// 则可以简写为f
scala> hf(println) // 第4个简化版本
higher