3

这个问题是关于合作伙伴今天遇到的一些语法,虽然我们了解它的工作原理,但我们不明白为什么允许它(它的用途是什么?)。

看看这个片段:

fun() -> ok end().

如果没有最后一对括号,这将产生如下内容:

#Fun<erl_eval.20.82930912>

但是有了它们,函数被评估产生:

ok

我的问题是,为什么 Erlang 允许使用这种语法?为什么我要创建一个函数来立即调用它而不是写出它的内容?它有什么实际用途吗?

我们唯一能想到的就是在 fun 的主体中引入局部变量(但这对我来说看起来很丑陋且不清楚)。

请注意,Erlang 中不允许使用这种其他语法即使它遵循与前者相同的概念:

fun() -> fun() -> ok end end()().  

(这意味着:一个返回函数 B 的函数 A。我正在评估 A(从而产生 B),然后评估 B 以获得'ok')。

4

2 回答 2

9

您提到的语法是 Erlang 功能化的自然结果。

在 Erlang 中,函数是值(存储为闭包)。

的值fun() -> ok end是一个函数,它不接受任何内容并返回ok。当我们在它后面加上括号时,我们正在调用该函数。另一种证明这一点的方法是:

 > F = fun() -> ok end.  
 #Fun<erl_eval.20.80484245>
 > F().                  
 ok

您的第二个示例中的函数需要正确分组,以便解析器理解它们。

至于你的问题——“为什么允许这种语法”,我不得不说这是函数在 Erlang 中作为值的自然结果。这种能力使编程的功能风格成为可能。这是一个例子:

 > lists:map(fun(X) -> X * 2 end, [1,2,3]).
 [2,4,6]

上面的代码本质上是这样的:

 > [fun(X) -> X * 2 end(1), fun(X) -> X * 2 end(2), fun(X) -> X * 2 end(3)].
 [2,4,6]

“自然结果”只是自然结果,它实际上不必有任何实际用途。所以,你可能永远不会看到像(fun() -> fun() -> ok end end())().被使用的代码:)

于 2013-09-12T23:26:55.920 回答
2

您通常不会对语法有太多用处fun() -> ok end ()。但是做类似的事情可能很有用(find_right_fun()) (),这基本上是相同的事情 - 一个计算为函数的表达式。

请注意,Erlang 解析器要求您使用 () 指定优先级以理清 ()() 的含义,即您的第二个示例应该是(fun() -> fun() -> ok end end()) ().

于 2013-09-12T21:38:09.733 回答