我正在浏览一些Elixir koans,我对这些代码行中发生的事情感到有点困惑。
def times_five_and_then(number, fun), do: fun.(number * 5)
def square(number), do: number * number
koan "You can pass functions around as arguments. Place an '&' before the name and state the arity" do
assert times_five_and_then(2, &square/1) == ___
end
对于___
,正确的答案是100.但我不知道如何或为什么,任何人都可以清楚地说明发生了什么?
&
是function capture运营商。 &square/1
的意思是“捕获名为square
的函数,它具有arity 1(简单英语中的arity 1:接受单个参数)”。
times_five_and_then(2, &square/1)
这意味着“用数字times_five_and_then
调用2
函数并捕获功能square
(具有arity 1)”。
存储在变量中的函数称为匿名函数(因为它没有名称,与使用def
关键字定义的函数不同)。可以使用&
捕获运算符将命名函数捕获为匿名函数,这是您的示例中发生的情况。
times_five_and_then/2
称其参数为number
和fun
。 fun
参数是包含匿名函数的变量。该函数可以是任何函数,但在您的示例中,它恰好是square/1
函数的捕获。调用匿名函数的语法是variable_name.(args)
。这就是fun.(number * 5)
在这种情况下发生的事情。存储在fun
中的函数正在使用参数number * 5
调用。
让我们看看times_five_and_then/2
的实现:
def times_five_and_then(number, fun), do: fun.(number * 5)
这需要fun
参数,并使用number
参数调用它包含的函数,乘以5
。发生了什么:
square/1
的函数,它将其参数平方。times_five_and_then/2
函数。times_five_and_then/2
函数将捕获的函数绑定到fun
变量。times_five_and_then/2
函数将其第一个参数(称为number
)乘以5。times_five_and_then/2
函数调用存储在fun
中的匿名函数(这是square/2
函数的捕获),具有上述乘法的结果。fun
中执行函数的结果。或者换句话说,2
乘以5
,然后传递给square/2
函数的捕获,该函数将其平方,得到100
。