Elixir:函数重载与不同的arity

tld*_*ldr 7 overloading function clause elixir arity

有没有办法用不同的arity定义重载函数,例如在C#中我可以这样做:

foo(bar)
Run Code Online (Sandbox Code Playgroud)

要么

foo(bar, baz)
Run Code Online (Sandbox Code Playgroud)

在Elixir中,唯一的方法是将它们放在单独的模块中,这将很快变得混乱.它有什么办法吗?

编辑:我做了一个错误的假设.我看到的重载函数的例子恰好具有相同的特性,所以我(错误地)认为这是一个要求.函数由其名称和arity唯一标识,因此您实际上可以使用不同的arity重载函数.

bit*_*ker 13

在Erlang和Elixir中,与许多其他语言(例如C#)不同,函数由它们的名称和arity唯一标识,因此在技术上foo(bar)foo(bar, baz)完全不同的功能.但这只是一个技术性问题,要在Elixir中编写一个"重载"函数,你会写出如下定义sum:

defmodule Math do
  def sum(list),       do: sum(list, 0)
  def sum([], acc),    do: acc
  def sum([h|t], acc), do: sum(t, acc + h)
end
Run Code Online (Sandbox Code Playgroud)

  • @tldr:正如bitwalker所说,sum/1和sum/2是不同的函数.功能由名称和arity标识. (3认同)
  • 如果你看到许多具有相同名称和arity的函数,那是因为其中一些函数在它们的参数上是模式匹配的,就像上面的例子中的`sum([],acc)`和`sum([h | t], ACC)`.在这种情况下,函数按源顺序进行尝试,所以当你调用`sum([1,2,3],0)`时,它将首先尝试匹配`sum([],acc)`这将失败因为`[1,2,3]`不是一个空列表,然后将尝试`sum([h | t],acc)`这将成功,因为列表有一个头和一个尾.您不能在参数上使用两个名称和arity相同的函数. (2认同)