2015-10-28 86 views
6

在靈藥,人們可以以兩種不同的方式定義 「求和」 功能:爲什麼在elixir中定義命名函數有兩種方法?

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 

我的問題是:爲什麼有兩種方法實現相同?在內聯函數的情況下,第二個是否首選?他們兩者的優點是什麼?

在此先感謝!

回答

11

do...end格式是do:格式的語法糖。

這不僅適用於功能外,還對ifcasecond

case 1, do: (1 -> "a") 

VS

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") 
相關問題