在Swift中,函數重載是合法的,也是常見的。這意味著具有相同函數名(包括外部參數名)的兩個函數可以共存,只要簽名不同即可。
比如,如下兩個函數可以共存:
func say (what:String) { } func say (what:Int) { }
重載可行的原因在於Swift擁有嚴格的類型。String一定不是Int。Swift能夠在聲明中將二者區分開,在函數調用時也能區分開。這樣,Swift就能夠毫無歧義地知道say("what")不同於say(1)。
重載也適用於返回類型。具有相同名字與相同參數類型的兩個函數可以有不同的返回類型。不過調用上下文一定不能有歧義;也就是說,一定要清楚調用者需要什麼樣的返回類型。
比如,如下兩個函數可以共存:
func say -> String { return "one" } func say -> Int { return 1 }
但現在就不能像下面這樣調用了:
let result = say // compile error
上述調用是有歧義的,編譯器會告訴你這一點。調用上下文一定要清楚期望的返回類型是什麼。比如,假設我們有另一個沒有重載的函數,它接收一個String參數:
func giveMeAString(s:String) { print("thanks!") }
那麼giveMeAString(say())就是合法的,因為只有一個String符合,因此我們必須調用返回String的say。與之類似:
let result = say + "two"
只有String可以「加到」String上,因此這個say()必須是個String。
如果之前用過Objective-C,那麼你會對Swift中重載的合法性感到驚訝,因為在Objective-C中是不允許重載的。如果在Objective-C中聲明了相同方法的兩個重載版本,那麼編譯器就會報「Duplicate declaration」錯誤。實際上,如果在Swift中聲明了兩個重載方法,但Objective-C卻能看到它們(參見附錄A瞭解詳情),那麼就會遇到一個Swift編譯錯誤,因為這種重載與Objective-C是不兼容的。
具有相同簽名和不同外部參數名的兩個函數並不構成重載;由於函數有著不同的外部參數名,因此它們是名字不同的兩個不同函數。