有没有办法用不同的arity定义重载函数,例如在C#中我可以这样做:
foo(bar)
或
foo(bar, baz)
在Elixir中,唯一的方法是将它们放在单独的模块中,这将很快变得混乱。有什么方法吗?
编辑:我做了一个错误的假设。我看到的重载函数的例子碰巧有相同的arity,所以我(错误地)认为这是一个要求。函数由其名称和arity唯一标识,因此您实际上可以使用不同的arity重载函数。
答案 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
)。