理解Elixir中的保护条款

我正试图在Elixir中实施一个保护条款 .

这就是我想要做的:

def fib(n) when n < 1, do: n

但是当我测试它时,会出现此错误:

** (FunctionClauseError) no function clause matching in ProjectEuler.fib/1

对于我的生活,我似乎无法理解这里的问题 .

回答(1)

3 years ago

从你提供的代码看起来你有一个只有一个功能的模块 - 这里显示的那个 . 我假设你有这样的事情:

defmodule MyModule do
  def fib(n) when n < 1, do: n
end

所以,如果您运行如下代码:

MyModule.fib(1)

这将失败 . 这是因为你的 fib/1 无法匹配,因为它有这个保护条款 when n < 1 .

为了使它通过,你需要添加另一个函数 - 限制较少(使用不同的保护子句,或没有任何保护子句):

defmodule MyModule do
  def fib(n) when n < 1, do: n
  def fib(n), do: fib(n-1) + fib(n-2)
end

这将使 MyModule.fib(1) 调用正确的定义 .

您需要注意 - 当使用此技术时,VM将尝试匹配参数分析函数定义,以便它们在模块中定义,因此:

defmodule MyModule do
  def fib(n), do: fib(n-1) + fib(n-2)
  def fib(n) when n < 1, do: n
end

将是有问题的,因为 fibwhen 子句永远不会匹配,因为首先定义的限制较少 .

希望有所帮助!