【发布时间】:2017-04-04 05:42:57
【问题描述】:
命名函数和匿名函数有什么区别?
hello = &("Hello, #{&1}") 是如何成为匿名函数的?
【问题讨论】:
命名函数和匿名函数有什么区别?
hello = &("Hello, #{&1}") 是如何成为匿名函数的?
【问题讨论】:
函数本身没有名称,它绑定到一个变量,但你可以将它内联放置在任何需要函数的地方,例如:
Enum.map([1,2,3], &("Hello, #{&1}") )
没有名字。匿名的。
【讨论】:
主要区别之一是范围。你可以在函数体中访问什么。
Elixir 中的命名函数被分组到模块中,它们的范围仅限于给它们的参数。
匿名函数可以在任何地方定义,并且可以访问其周围可见的任何内容。行话是它们是“闭包”,即它们“关闭”周围的范围。
我们来看一个例子:
c = 10
anon = fn(a, b) -> a + b + c end
anon.(1, 2) # => 13, because c is available in the anonymous function
# The module below will fail to compile, because c isn't available
defmodule MyModule do
def named(a, b), do: a + b + c
end
您可以使用 & capture operator 从命名函数创建匿名函数,并且它可以访问您当前的作用域。这很常见,因为许多函数都期望其他函数作为参数。浏览the docs for Enum,你会看到很多例子。
你会注意到我这样调用匿名anon 函数:anon.(1, 2),而不是anon(1, 2)。它使两种函数之间的区别在您的代码中更加明确。
José 对related question 给出了很好的回答。
【讨论】:
命名函数需要在模块中定义。匿名函数没有这个限制。
在您的示例中,&("Hello, #{&1}") 是匿名函数部分。它使用捕获操作符 &,所以这个函数只是写fn (x) -> "Hello, #{x}" end的更短的方式。 &1 是函数参数的占位符。您可以将该匿名函数分配给一个变量(在这种情况下为hello)。要通过变量访问函数,请使用 hello.("Derek")。 别忘了点!
请记住,Function 也是 Elixir 中的一种类型,并且函数是一等公民,这就是为什么您可以将其分配给变量并使函数返回其他函数的原因。
【讨论】: