如何理解Swift中Optional的 和

2021-08-08 01:38:06 字數 2461 閱讀 8619

很多人在剛上手swift時對於optional中 『!』 和 『?』 的使用十分不理解,接下來我會談一談自己對於這兩個符號的使用方式的理解。

先來說說optional的概念,以方便之後的理解。來看一下下面的**:

var a : string = nil

// 編譯錯誤,string型別不能為nil

var b : string = 「hello!」

swift 中的普通型別不再能設為nil。那如何表示這個值不存在呢?所以引進了optional的概念:代表 nil 或某個具體的值。例如:

var c : string? = nil

var d : string? = 「hello!」

string? 就是乙個optional,它既能夠被具體型別賦值, 也可以賦值為nil。通過 string 和 optional的比較,發現optional 就相當於把具體型別和 nil 打包**在了一起,轉變成了一種新的型別。

optional 有兩種宣告方法:

var bread: string!

很多人認為,宣告為 string! 的變數表明該變數的值不為 nil。但是,實際上,string! 和 string? 都是有預設值的,且預設值都為nil。我們為它們賦乙個初值再列印型別來看看:

var bread: string! = 「bread」

(string

?) $r0

(lldb) p bread

(string

?) $r1

= 「bread」

為了之後敘述方便,我們把定義類似 string? 的稱為 optional(?), 定義類似 string! 的稱為 optional(!)。

optional 的本質是囊括 nil 和具體型別的一種列舉。獲取它具體值的操作過程稱之為拆包,用 「!」 表示。先來做個實驗:

var

string : string

var optionalstring: string?

var nonoptionalstring: string!

string = nonoptionalstring // ① 崩潰

string = optionalstring // ② 編譯錯啦

string = optionalstring! // ③ 崩潰

具體看一下報錯原因:

① string! 賦值給 string ,報錯為:拆包時optional的值為nil;

② string? 賦值給 string,編譯器報錯為 optional未拆包;

③ 拆包後的 string? 賦值給 string,這時,報錯為:拆包時optional的值為nil;

但是,只有在變數確認有值的情況下才能進行拆包。就像如上**,optionalstring 為nil,進行拆包就會引發崩潰。swift官方建議,optional 使用 if + ! 結合的方式或者 if let 進行安全地拆包。簡單的看下**:

if optionalstring != nil  else
if

let actualstring = optionalstring else

再次提醒一下,optional(!) 和 optional(?) 都可以使用這兩種方式進行安全地拆包,只是編譯器不會對沒有處理 nil 情況的 optional(!) 報錯。下圖展示了 optional和 string 可接收型別的比較:

拆完包之後的 optional其實就是 string 型別。編譯器強制使用者在變數為 nil 的時候要進行處理,否則就會報錯會崩潰。string! 是為了規避變數一定不為 nil 的情況下卻要反覆判斷是否為 nil 的冗餘**而產生的。例如,我們在使用 iboutlet 時,一定會定義成 optiona(!)。string! 在宣告時和 string? 完全等價,在使用時和 string 完全等價。

總結一下:

optional的本質是乙個包含了 nil 和普通型別的列舉,這是為了確保使用者在變數為 nil 的情況下會完成相應的處理;

無論是 optional(!) 還是 optional(?) 都是一種optional,在未設初始值時,預設為nil。optional(!) 只是給予了自動拆包的許可權,省略了判斷其值是否為nil的過程,但是不能夠保證它的值不為nil;

optional(!) 在宣告時和 optional(?) 等價,在使用時和具體型別等價;

Swift 中如何理解copy on write

當值型別 如struct 在複製時,複製的物件和元 原物件實際上在記憶體中指向同乙個物件。當且僅當修改複製後的物件時,才會在記憶體中重新建立乙個新的物件。舉例 arraya是乙個陣列,為值型別 let arraya 1,2,3 arrayb這個時候與arraya在記憶體中是同乙個陣列,記憶體中並沒有...

如何理解 Swift 中的類 屬性和方法?

教程都會說得比較嚴謹,所以會有點不好理解,其實很簡單,我舉個例子 我們先建立乙個類,叫student class student然後我們希望每乙個student都有乙個功能,就是呼叫他們的時候他們都能說出自己的名字,所以我們先在類裡面初始化乙個型別為string 字串 的屬性,名字為name cla...

Swift 中如何擷取String

swift 中擷取字串的方式非常麻煩,但是在oc中的字串擷取卻比較便捷,要擷取string 只需要將string 轉化為nsstring 在進行擷取就可以了 示例 如下 let mystr www.520it.com var substr mystr as nsstring substringfro...