首页 > 解决方案 > 添加可选参数 elixir 导致函数 def 冲突

问题描述

该功能hello没有任何冲突并且工作正常。

defmodule User do
  defstruct [:name]
end

defmodule Greeter do
  def hello(%User{} = user) do
    "Hello #{user.name}"
  end

  def hello(name) do
    "Hello #{name}"
  end
end

但是,如果我在第一个函数中添加可选参数,则会出现冲突错误。

...
  def hello(%User{} = user, opts \\ []) do
    "Hello #{user.name}"
  end
...

错误 def hello/1 conflicts with defaults from hello/2

谁能解释这为什么以及如何有意义?

标签: elixirdefault-parameters

解决方案


def hello/1 与 hello/2 的默认值冲突

这意味着编译器不知道是否hello("foo")意味着:

  • 调用hello/1with"foo"作为参数。
  • 调用hello/2with"foo"作为第一个参数和默认的第二个参数。

它不知道这一点,因为两者具有相同的调用语法,但是子句可以以不同的方式实现。

您可以首先使用默认值声明函数签名,然后定义使用该默认值的实现。我认为最好只定义一个返回的最终结果,并将"Hello #{name}"该行为包装在另一个函数子句中:

def hello(user, opts \\ [])
def hello(%User{name: name}, opts), do: hello(name, opts)
def hello(name, _opts), do: "Hello #{name}"

推荐阅读