Elixir:函数重载与不同的arity

时间:2014-05-12 03:14:18

标签: function overloading clause elixir arity

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

foo(bar)

foo(bar, baz)

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

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:2)

关于这个page,请参阅第8.3节及以下内容。特别是:

函数声明还支持警卫和多个子句。如果函数有多个子句,Elixir将尝试每个子句,直到找到匹配的子句。这是一个函数的实现,它检查给定的数字是否为零:

defmodule Math do
  def zero?(0) do
    true
  end

  def zero?(x) when is_number(x) do
    false
  end
end

Math.zero?(0)  #=> true
Math.zero?(1)  #=> false

Math.zero?([1,2,3])
#=> ** (FunctionClauseError)

在单个模块中具有多个重载的相同函数名称(尽管在文档中称为clauses)。