Elixir:模式匹配函数签名

时间:2018-06-14 20:02:39

标签: elixir

我试图创建一个接受两个列表作为参数的函数,并且每个列表都是(a)不为空,(b)是某个结构的列表。这样的事情可以满足我的需求:

def zip_sports_and_leagues(
  [%Sport{} | _tail] = sports,
  [%League{} | _tail] = leagues
) do
  # Do stuff with `sports` and `leagues`
end

我得到一个"没有函数子句匹配"当第一个列表有多个项目时,该函数出错。

我已经将代码剥离到这个最小的例子:

defmodule Test do
  def test([a | _tail], [b | _tail]) do
    1
  end
end

Test.test([1], [1])
=> 1

Test.test([1, 1], [1])
** (FunctionClauseError) no function clause matching in Test.test/2

    The following arguments were given to Test.test/2:

        # 1
        [1, 1]

        # 2
        [1]

有人可以告诉我为什么我会收到函数子句错误以及如何修复它?

谢谢!

1 个答案:

答案 0 :(得分:8)

问题在于您为两个参数的尾部使用相同的名称:_tail。当函数的参数中的名称被使用两次时,该子句仅在两者具有相同值时匹配。您可以重命名其中一个:

def zip_sports_and_leagues(
  [%Sport{} | _tail] = sports,
  [%League{} | _tail2] = leagues
) do
  # Do stuff with `sports` and `leagues`
end

或使用_,它不会绑定该值,并且可以多次使用:

def zip_sports_and_leagues(
  [%Sport{} | _] = sports,
  [%League{} | _] = leagues
) do
  # Do stuff with `sports` and `leagues`
end