2017-06-23 125 views
1

我開始讓我的頭在optionals和強制解包,除了在一個特定的上下文中:當它是一個函數的返回類型。強制解包返回類型?

之間有什麼區別:

func myFunction() -> NSData { ... } 

func myFunction() -> NSData! { ... } 

func myFunction() -> NSData? { ... } 

此外,當我使用的NSData!一個返回值,我被迫使用?這似乎很奇怪。

func myFunction() -> NSData! { ... } 
let data = myFunction() 
data?.write() 

爲什麼我需要?如果我強制解開回報?上述

+0

可能是重複https://stackoverflow.com/questions/24061039/how-is-a-return-value-of-anyobject-different-from-anyobject – rmaddy

+1

對於'NSData',這兩者之間沒有什麼不同兩行代碼。你可以在@rmaddy發送的鏈接中找到Rob的一個很好的解釋。 – Lawliet

+3

在實踐中**從不**使用隱式展開的可選值作爲函數/方法中的返回類型。這個值可以是'nil',然後使用'?'或者該值永遠不會'nil',然後使用'non-optional'。 – vadian

回答

3
func myFunction() -> NSData { ... } 

意味着myFunction返回NSData一個實例。上述


func myFunction() -> NSData? { ... } 

意味着myFunction返回Optional<NSData>型(也稱爲NSData?)的值。 Optionalenum,有兩種情況:.some(value).none(也稱爲nil)。因此該函數返回NSData(包裝在.some的情況下)或nil。上述


func myFunction() -> NSData! { ... } 

意味着myFunction返回Optional<NSData>類型,就像在前面的例子中NSData?返回類型的值。

但是,使用!意味着,如果您使用myFunction()的值的方式不進行類型檢查,編譯器會嘗試爲您打開返回的值。所以,如果你這樣說:

let maybeLength = myFunction()?.length 

那麼編譯器會看到,你是治療的myFunction返回值作爲Optional<NSData>。但是,如果你這樣說:

let dataLength = myFunction().length 

那麼編譯器會看到Optional<NSData>沒有length成員,因此它會假裝你寫了這個:

let dataLength = myFunction()!.length 

,如果可以編譯,它會繼續。

此行爲在Swift Evolution proposal SE-0054, Abolish ImplicitlyUnwrappedOptional type中定義。


現在我們終於可以這樣考慮:

func myFunction() -> NSData! { ... } 
let data = myFunction() 
data?.write() 

什麼是data類型?編譯器必須根據=右側的表達式推斷出data的類型。正如我在上面的例子中解釋的那樣,myFunction()的類型是Optional<NSData>。所以data的類型是Optional<NSData>,也叫NSData?

編譯器沒有遇到任何問題,使得data的類型爲NSData?,所以它沒有理由隱式地解開返回值myFunction

+0

太棒了!謝謝! –