这次需要谈到函数式编程语言中的基础–高阶函数,简单的说就是将函数(方法)作为参数传递给另一个函数。
先来看一个简单的例子:
-module(hhfuns).
-compile(export_all).
one() -> 1.
two() -> 2.
add(X,Y) -> X() + Y().
打开Erlang Shell进行运行尝试,如下:
1> c(hhfuns).
{ok, hhfuns}
2> hhfuns:add(one,two).
** exception error: bad function one
in function hhfuns:add/2
3> hhfuns:add(1,2).
** exception error: bad function 1
in function hhfuns:add/2
4> hhfuns:add(fun hhfuns:one/0, fun hhfuns:two/0).
3
相信你已经注意到了,将函数作为参数传递时,需要特别的说明,基本语法为fun Module:Function/Arity:。至于函数式编程有什么好处,我就不多说了,相信网上有很多答案,我个人体验来说,可以很方便的实现策略模式。
匿名函数
匿名函数的定义和普通函数类似,只是函数名固定为fun,简单的例子如下所示:
102> Fnc = fun() -> 1 end.
#Fun<erl_eval.20.54118792>
103> Fnc().
1
104>
接下来看一个更复杂一点的例子:
11> PrepareAlarm = fun(Room) ->
11> io:format("Alarm set in ~s.~n",[Room]),
11> fun() -> io:format("Alarm tripped in ~s! Call Batman!~n", [Room]) end
11> end.
#Fun<erl_eval.20.67289768>
12> AlarmReady = PrepareAlarm("bathroom").
Alarm set in bathroom.
#Fun<erl_eval.6.13229925>
13> AlarmReady().
Alarm tripped in bathroom! Call Batman!
ok
在这个例子中,函数作为返回值,而此函数中的变量Room是来自于父函数,这个就关系到一个概念–闭包。在erlang中,子函数的作用域继承自父函数(但父函数不能访问子函数的变量),因此当你将自函数作为返回参数时,子函数仍然能够访问父函数中的变量,这样就形成了一个闭包。