可選型別是swift中新引入的,功能很強大。在這篇博文裡討論的,是在swift裡,如何通過可選型別來保證強型別的安全性。作為例子,我們來建立乙個objective-c api的swift版本,但實際上swift本身並不需要這樣的api。
為dictionary增加objectsforkeys函式
在objective-c中,nsdictionary有乙個方法-objectsforkeys:nofoundmarker:, 這個方法需要乙個nsarray陣列作為鍵值引數,然後返回乙個包含相關值的陣列。文件裡寫到:"返回陣列中的第n個值,和輸入陣列中的第n個值相對應",那如果有某個鍵值在字典裡不存在呢?於是就有了notfoundmarker作為返回提示。比如第三個鍵值沒有找到,那麼在返回陣列中第三個值就是這個notfoundmarker,而不是字典中的第三個值,但是這個值只是用來提醒原字典中沒有找到對應值,但在返回陣列中該元素存在,且用notfoundmarker作為佔位符,因為這個物件不能直接使用,所以在foundation框架中有個專門的類處理這個情況:nsnull。
在swift中,dictionary類沒有類似objectsforkeys的函式,為了說明問題,我們動手加乙個,並且使其成為操作字典值的通用方法。我們可以用extension來實現:
複製** **如下:
extension dictionary
}以上就是我們實現的swift版本,這個和objective-c版本有很大區別。在swift中,因為其強型別的原因限制了返回的結果陣列只能包含單一型別的元素,所以我們不能放nsnull在字串陣列中,但是,swift有更好的選擇,我們可以返回乙個可選型別資料。我們所有的值都封包在可選型別中,而不是nsnull, 我們只用nil就可以了。
複製** **如下:
extension dictionary
return result
}}swift中更簡便的方法
小夥伴們可能會問,為什麼swift中不需要實現這麼乙個api呢?其實其有更簡單的實現,如下面**程式設計客棧所示:
複製** **如下:
extension dictionary
}}上述方式實現的功能和最開始的方法實現的功能相同,雖然核心的功能是封裝了map的呼叫,這個例子也說明了為什麼swift沒有提供輕量級的api介面,因為小夥伴們簡單的呼叫map就可以實現。
接下來,我們實驗幾個例子:
複製** **如下:
var dic: dictionary = [ "1": 2, "3":3, "4":5 ]
var t = dic.valuesforkeys(["1", "4"])
//結果為:[optional(2), optional(5)]
var t = dict.valuesforkeys(["3", "9"])
// 結果為:[optional(3), nil]
t = dic.valuesforkeys()
//結果為:
內嵌可選型別
現在,如果我們為每乙個結果呼叫last方法,看下結果如何?
複製** **如下:
var dic: dictionary = [ "1": 2, "3":3, "4":5 ]
var t = dic.valuesforkeys(["1", "4"]).last //結果為:optional(optional(5))
// optional(optional("ching"))
var t = dict.valuesforkeys(["3", "9"]).last
// 結果為:optional(nil)
var t = dict.valuesforkeys().last
// 結果為:nil
小夥伴們立馬迷糊了,為什麼會出現兩層包含的可選型別呢?,特別對第二種情況的optional(nil),這是什麼qwdyiiua節奏?
我們回過頭看看last屬性的定義:
複製** **如下:
var last:t?
很明顯last屬性的型別是陣列元素型別的可選型別,這種情況下,因為元素型別是(string?),那麼再結合返回的型別,於是其結果就是string??了,這就是所謂的巢狀可選型別。但巢狀可選型別本質是什麼意思呢?
如果在objective-c中重新呼叫上述方法,我們將使用nsnull作為佔位符,objective-c的呼叫語法如下所示:
複製** **如下:
[dict valuesforkeys:@[@"1", @"4"] notfoundmarker:[nsnull null]].lastobject
// 5
[dict valuesforkeys:@[@"1", @"3"] notfoundmarker:[nsnull null]].lastobject
// nsnull
[dict valuesforkeys:@ notfoundmarker:www.cppcns.com[nsnull null]].lastobject
// nil
不管是swift版本還是objective-c版本,返回值為nil都意味陣列是空的,所以它就沒有最後乙個元素。 但是如果返回是optional(nil)或者objective-c中的nsnull都表示陣列中的最後乙個元素存在,但是元素的內容是空的。在objective-c中只能借助nsnull作為佔位符來達到這個目的,但是swift卻可以語言系統型別的角度的實現。
提供乙個預設值
進一步封裝,如果我字典中的某個或某些元素不存在,我們想提供乙個預設值怎麼辦呢?實現方法很簡單:
複製** **如下:
extension dictionary
}}dict.valuesforkeys(["1", "5"], notfoundmarker: "anonymous")
和objective-c相比,其需要佔位符來達到佔位的目的,但是swift卻已經從語言型別系統的層面原生的支援了這種用法,同時提供了豐富的語法功能。這就是swift可選型別的強大之處。同時注意上述例子中用到了空合運算子??。
本文標題: swift中使用可選型別完美解決佔位問題
本文位址: /ruanjian/swift/125304.html
Swift 可選型別完美解決佔位問題
可選型別是swift中新引入的,功能很強大。在這篇博文裡討論的,是在swift裡,如何通過可選型別來保證強型別的安全性。作為例子,我們來建立乙個objective c api的swift版本,但實際上swift本身並不需要這樣的api。為dictionary增加objectsforkeys函式 在o...
Swift 可選型別
swift 可選型別 optionals 可選型別 強制解析 自動解析 可選繫結 1.可選型別 加入我們建立乙個變數,但是它有可能為空,這時候swift提供乙個符號 來表示這是乙個可能為空的變數 var thisstr string?看到這裡的if,沒錯,if或者for迴圈後面的內容不加 加了也沒錯...
Swift 可選型別
在 swift 中,可選型別用來處理值可能缺失的情況,表示下面兩種情況 在 swift 中宣告變數時,使用?或 來表示宣告的變數是可選型別。let name string?var age int 此時,變數name和age預設都是nil,表示空。而?和 的區別在於使用前者宣告的變數所包含的值時,需要...