【发布时间】:2016-05-28 06:42:16
【问题描述】:
我有以下灵药代码sn-p:
defmodule Rectangle do
def area(a, b) do
a * b
end
def area(a) do
a * a
end
end
然后我将文件加载到 iex 会话中,如下所示:
iex(1)> import_file "rectangle.exs"
{:module, Rectangle,
<<70, 79, 82, 49, 0, 0, 5, 84, 66, 69, 65, 77, 69, 120, 68, 99, 0, 0, 0, 204, 131, 104, 2, 100, 0, 14, 101, 108, 105, 120, 105, 114, 95, 100, 111, 99, 115, 95, 118, 49, 108, 0, 0, 0, 4, 104, 2, ...>>,
{:area, 1}}
效果如我所愿
iex(2)> Rectangle.area(9)
81
现在我想将具有 arity 1 的区域函数分配给匿名函数,例如:
iex(3)> fun = Rectangle.area/1
** (UndefinedFunctionError) undefined function Rectangle.area/0
Rectangle.area()
但是当我输入类似:
iex(3)> fun = &Rectangle.area/1
&Rectangle.area/1
然后就可以了。虽然 Rectangle.area 已经是函数了,但是为什么elixir 函数名前面要加 &?
【问题讨论】:
-
这是一个公正的语法问题 - 它有点像解释器说“指向函数的指针”不是代数表达式(例如格式错误的除以 1)。请记住,Elixir 正在做“杂技”以保持与 Erlang 的兼容性 - 所以必须做出一些妥协 - 我认为。
-
@GavinBrelstaff 这实际上有两个原因。第一个是因为在 Elixir 语法中,parens 是可选的,引用一个函数只会调用它,除非你使用
&来表示命名函数和 arity(它需要的参数数量)。第二个原因是 Elixir 没有做任何杂技来保持与 Erlang 的兼容性,它只是假设了 Erlang 的所有语义。在 Beam VM 中,函数由名称和数量来标识。同名有 2 个 arities 实际上是 2 个不同的函数。 -
感谢 asonge - 我也是来学习的!仍然 IMO 允许括号在任何地方都是可选的,这对我们的用户来说非常棒,但对于维护语言的人来说,无论是否“杂技”都具有挑战性。
-
关于不同种类的功能很好的解释可以看这个answer
标签: elixir