2015-01-11 48 views
5

我寫了這個代碼在操場測試(學習)用途:使用和不使用默認參數聲明的調用函數導致不同的結果?

import Cocoa 
func DoIt(a: Int, b: Int, c :Int = 0) -> Int { 
    return a + b + c; 
} 
func DoIt(a: Int, b: Int, c :NSObject) -> Int { 
    return a * b * c.description.lengthOfBytesUsingEncoding(NSUTF8StringEncoding); 
} 

當我使用它,我得到這個:

DoIt(4, 5, 6);   // result: 20 
var obj = NSObject();  // result: NSObject 
DoIt(4, 5, obj);   // result: 520 

我做DoIt(4, 5, 6);時所預期的第一個函數DoIt(Int, Int, Int)調用,但顯然另一個被稱爲。 6去哪了?它看起來像6被隱式轉換爲NSObject,在Objective-c中至少會引發警告。
這是爲什麼?

奇怪的是,如果我要求最後c: Int(通過刪除= 0)然後它按預期工作。

DoIt(4, 5, 6);   // result: 15 
var obj = NSObject();  // result: NSObject 
DoIt(4, 5, obj);   // result: 520 

EDIT1:增加IR
如果這有助於瞭解對我發出以下命令,結果是要點鏈接是怎麼回事:https://gist.github.com/nacho4d/94fdb72d8a3fee0c09e5

$ swiftc \ 
    -emit-ir /Users/nacho4d/Desktop/function2/function2/main.swift \ 
    -sdk Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk 
+0

有在reddit上的一個線程,也許它有幫助:[爲什麼Swift編譯器隱式地將整數和其他原語轉換爲NSNumber](http://www.reddit.com/r/swift/comments/2em7ic/why_swift_compiler_convert_implicitly_integers/) –

+0

我不知道爲什麼它工作這w唉,但我不相信這是有意的行爲。如果是的話,我覺得很奇怪。 – Dair

+0

謝謝@SebastianDressler我剛剛讀了那個帖子。我理解隱式裝箱(原始到NSNumber)及其相反的拆箱。但我不確定這是否是這種情況。這仍然不清楚我 – nacho4d

回答

4

來自Swift文檔中的"Functions"(強調增加):

帶缺省值的參數的外部名稱

在大多數情況下,爲任何具有缺省值的參數提供(因此需要)外部名稱很有用。這確保 如果在調用該函數時提供的值爲 ,則該參數的參數明確是有意的。

爲了使這個過程更容易,斯威夫特有一個默認值任何參數提供了一個自動體外名 。自動外部 名稱與本地名稱相同,就好像您已在代碼中的本地名稱之前寫了散列 符號。

所以你的第一個函數聲明

func DoIt(a: Int, b: Int, c : Int = 0) -> Int 

是由編譯器視爲

func DoIt(a: Int, b: Int, c c : Int = 0) -> Int 

與外部參數名 「C」 的第三個參數。此功能 將不得不只稱爲

DoIt(4, 5, c: 6) // result: 15 

但通話

DoIt(4, 5, 6) 

不匹配你的第一個函數的聲明,即其它功能的

func DoIt(a: Int, b: Int, c :NSObject) -> Int 

(第三個參數自動橋接到NSNumber,這是一個子類 的NSObject)。這就是爲什麼你會得到「意外」輸出。

如果你改變了第一個函數來

聲明
func DoIt(a: Int, b: Int, _ c : Int = 0) -> Int 

(其中_表示「不對外參數名」) 那麼你會得到預期的輸出:

DoIt(4, 5, 6) // result: 15 
+0

這解釋了很多東西!現在我清楚地看到,對於具有可選參數的函數,我需要使用外部參數名稱或在聲明中使用'_'。然而,我仍然不明白'Int'是如何隱含地轉換成'NSObject'的? – nacho4d

+1

@ nacho4d:Swift自動將特定的本地類型(Int,Float,Bool,...)橋接到NSNumber,NSNumber是NSObject的一個子類。你可以在[在Cocoa和Objective-C中使用Swift](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/)閱讀關於它的更多信息,「使用Cocoa數據類型」。 - 我已經更新了答案,使其更加清晰。 –

+0

我明白了!非常感謝! – nacho4d

相關問題