我正在经历一些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。但是我不确定如何或为什么,有人可以清楚地说明正在发生的事情吗?
答案 0 :(得分:2)
&
是function capture运算符。 &square/1
的意思是“捕获称为square
的函数,该函数具有arity 1(简单英语中的arity 1:接受单个参数)”。
times_five_and_then(2, &square/1)
这意味着“用数字times_five_and_then
调用2
函数并捕获函数square
(具有偶数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
。