2015-08-21 42 views
3

我只是想用在雨燕.map關閉和偶然發現了這一點:雨燕VS明確解開類型

//var oldUsers = [User]() -> containting >=1 Users at runtime 
//var invitedUsers = [String]() -> gets filled with userIds during runtime by the user clicking on people to invite 

let oldIds = self.oldUsers.map {$0.userId} //userId is of Type String! 
println(oldIds) //-> returns Array<String!> 

var allUsers = self.invitedUsers + oldIds 

最後一行不會編譯,因爲它說你不能結合

[(String)] and Array<String!> 

快速通過在地圖上進行演員表來修復它

let oldIds = self.oldUsers.map {$0.userId as String} 

不應該這樣嗎?我會理解,如果我需要首先打開一個可選的[String?]數組。爲什麼需要強制轉換,因爲object屬性已經是一個明確展開的String類型了?

回答

4

[(String)]Array<String!>並不完全相同。

而且,String!明確展開,而是隱含展開。它被稱爲隱式解包,因爲我們可以嘗試使用它作爲String而不顯式編寫任何解包代碼。同時,明確寫入展開代碼被稱爲明確展開...

但是在一天結束時,要點是[String][String!]是不同的類型。他們似乎足夠接近,但斯威夫特是非常嚴格的其類型。

將這兩個數組組合的結果是什麼?應該是[String]?或者一個[String!]?無論哪種方式,它與進入它的兩種類型不一樣,所以它會混淆。沒有一個合理的方法來確定它應該是什麼樣的數組。

那麼你的選擇是要麼投的[String!][String],並希望它沒有保持nil值,或鑄[String][String!],然後你就可以結合起來。

+1

我建議使用'flatMap'而不是'map'將是最好的選擇,避免了將'String!'強制轉換爲'String'的危險,並確保該數組可以安全地用於其中。當然, ,如果'nil'' userId'是一個編程錯誤,那麼堅持使用cast - 你想讓它崩潰。 – Stuart

+1

我建議不要使用'String!'或'[String!]'。唯一的原因是,如果你使用了一些可怕的Objective-C庫,它設法更新到類型數組,但錯過了關於可空性註釋的部分。 – nhgrif

0

因爲您沒有明確給出您的封閉類型,所以Swift會爲您推斷它。

總之,我認爲您鑄造封閉的結果類型是有點怪,並且使用完全封閉的語法會更好: let oldIds = self.oldUsers.map {(user) -> String in user.userId}

這裏你明確告訴雨燕,你的封返回類型爲String,所以地圖結果類型應爲[String]

+0

[-1] Swift的類型推斷沒有什麼不尋常的事情發生。 'oldIds'被推斷爲'[String!]',因爲'user.userId'的類型是'String!'。此外,編寫完整閉包語法的建議與使用'as'運算符(它只是使閉包推斷返回類型爲String)沒有什麼不同,除了它稍微冗長些。 – Stuart

+0

你說得對,我以爲userId是String類型的。關於閉包語法,我並不是說它不同,但有時冗長是件好事。 – afraisse