作为参数的功能-这里发生了什么?

时间:2019-04-06 06:51:24

标签: elixir

我正在经历一些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。但是我不确定如何或为什么,有人可以清楚地说明正在发生的事情吗?

1 个答案:

答案 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调用其参数numberfunfun参数是一个包含匿名函数的变量。该函数可以是任何函数,但是在您的示例中,它恰好是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来调用它包含的函数。发生的事情的细分:

  1. 定义了一个名为square/1的函数以平方其参数。
  2. square函数被捕获为匿名函数,并作为第二个参数传递给times_five_and_then/2函数。
  3. times_five_and_then/2函数将捕获的函数绑定到fun变量。
  4. times_five_and_then/2函数将其第一个参数number乘以5。
  5. times_five_and_then/2函数调用存储在fun中的匿名函数(这是square/2函数的捕获),并通过上述相乘得到结果。
  6. 返回fun中函数的执行结果。

或者换句话说,将2乘以5,然后传递给square/2函数的捕获,将其平方,得到100