为啥在 elixir 中定义命名函数有两种方式?
Posted
技术标签:
【中文标题】为啥在 elixir 中定义命名函数有两种方式?【英文标题】:Why are there two ways to define named functions in elixir?为什么在 elixir 中定义命名函数有两种方式? 【发布时间】:2016-01-28 12:06:39 【问题描述】:在 elixir 中,可以用两种不同的方式定义“sum”函数:
def sum, do: 0
def sum(a), do: a
def sum(a, b), do: a + b
def sum(a, b, c), do: a + b + c
或
def sum() do 0 end
def sum(a) do a end
def sum(a,b) do a + b end
def sum(a,b,c) do a + b+ c end
我什至可以混合使用这两种方法:
def sum() do 0 end
def sum(a) do a end
def sum(a,b) do a + b end
def sum(a,b,c), do: a + b + c
我的问题是:为什么有两种方法可以达到相同的效果?在内联函数的情况下,第二个是首选吗?它们各自的优点是什么?
提前致谢!
【问题讨论】:
【参考方案1】:do...end
格式是do:
格式的语法糖。
这不仅适用于函数,也适用于if
、case
、cond
等。
case 1, do: (1 -> "a")
对
case 1 do
1 -> "a"
end
一般来说,do...end
格式是首选,除非函数定义短到可以放在一行中。
do
在这种情况下实际上是关键字列表中的一个参数。 if
宏的实现类似于:
do_clause = Keyword.get(clauses, :do, nil)
else_clause = Keyword.get(clauses, :else, nil)
这将获取do...else...end
块内的表达式:
if foo do
#this gets stored in do_clause
else
#this gets stored in else_clause
end
注意if
的实现略有变化,你可以在https://github.com/elixir-lang/elixir/blob/1a7412502fd581da8ef1378fcd5a057ab96378f7/lib/elixir/lib/kernel.ex#L2294看到我指的版本
【讨论】:
【参考方案2】:这是为了程序员的方便。以任何上述方式定义函数不会对实际函数产生任何影响。
do..end
是do:
的语法糖。这意味着它是一种使事情更容易阅读或表达的语法。它使人类使用的语言“更甜”:可以更清晰、更简洁地表达事物,或者以某些人可能更喜欢的另一种风格表达。[wikipiedia]
一般而言,do:
语法适用于单行,do..end
适用于多行
def count(limit), do: count(1,limit)
defp count(current,limit) when current <= limit do
IO.inspect(current)
count(current+1,limit)
end
#The underscore means we dont care what the arguments are
defp count(_,_), do: IO.puts("finished")
【讨论】:
以上是关于为啥在 elixir 中定义命名函数有两种方式?的主要内容,如果未能解决你的问题,请参考以下文章
Elixir:应用程序立即退出,或者在运行 distillery 包时没有收到输入。为啥它会以这种方式工作,以及如何解决它?