相信大家在學習和使用swift的時候,肯定會被!
和?
搞瘋過, 糾結這兩個符號到底是個什麼鬼 ?鬼知道什麼時候使用!
,什麼時候使用?
下面就說一下!
和?
區別以及該怎麼使用!
?
和!
其實分別是swift語言中對一種可選型別( optional) 操作的語法糖。 那可選型別是幹什麼的呢? swift中是可以宣告乙個沒有初始值的屬性, swift中引入了可選型別(optional)來解決這一問題。它的定義是通過在型別生命後加加乙個?
操作符完成的。
例如:var name: string?
optional
其實是個enum
,裡面有none
和some
兩種型別。其實所謂的nil就是optional.none
, 非nil就是optional.some
, 然後會通過some(t)
包裝(wrap)原始值,這也是為什麼在使用optional
的時候要拆包(從enum
裡取出來原始值)的原因。
這裡是enum optional的定義
enum optional: logicvalue, reflectable
既然這樣, 那對於var name: string?
該怎樣去理解這句語法呢?
var name: string?
// 上面這個optional的宣告,是」我宣告了乙個optional型別值,它可能包含乙個string值,也可能什麼都不包含」,也就是說實際上我們宣告的是optional型別,而不是宣告了乙個string型別 (這其實理解起來挺蛋疼的...)
一旦宣告為optional
的,如果不顯式的賦值就會有個預設值nil
。判斷乙個optional
的值是否有值,可以用if來判斷:
if name
怎麼使用optional
值呢?文件中也有提到說,在使用optional
值的時候需要在具體的操作,比如呼叫方法、屬性、下標索引等前面需要加上乙個?
,如果是nil
值,也就是optional.none
,會跳過後面的操作不執行,如果有值,就是optional.some
,可能就會拆包(unwrap),然後對拆包後的值執行後面的操作,來保證執行這個操作的安全性。
// 例如:
let length = name?.characters.count
ps:對於optional
值,不能直接進行操作,否則會報錯。
?
的使用場景:
1.宣告optional
值變數
2.用在對optional
值操作中,用來判斷是否能響應後面的操作
3.使用as?
向下轉型(downcast)
上面提到optional
值需要拆包(unwrap)後才能得到原來值,然後才能對其操作,那怎麼來拆包呢?
拆包有兩種方法:
// 例子最為簡單明瞭
var str: string? = "hello"
let greeting = "world!"
if let name = str
/**自然語言解釋意思:就是如果str有值,解包它,並且將它的值賦值給name, 然後執行下面的條件語句; 如果str為空, 直接跳過條件語句塊。
*/
var str1: string? = "hello"
let greeting = "world!"
if (str1 != nil)
/**上面例子,我們只是自己知道str1肯定有值, 所以才直接硬解包了str1變數。 但是萬一有時候我們的感覺是錯的, 那程式在執行時可能會出現嚴重的錯誤. 所以swift中是推薦先檢查可選型別是否有值, 然後再進行解包的!
*/
錯誤示範:
var str1:string? // str1值可能是傳過來的值或者從伺服器獲取的值
let msg = "hi"
let txt = msg + str1! // runtime error
/** 以上**在編譯階段不會報錯.因為使用了硬解包, 編譯器認為可選型別是有值的, 所以編譯是通過的. 當**執行起來時, 知名的錯誤將會出現: `fatal error: can』t unwrap optional.none`
*
ps:對於!
操作符,這裡的變數值一定是非nil的!
舉個很淺顯的栗子:
// 在乙個viewcontroller裡面,從xib裡面拖乙個uiimageview控制項, 你會發現xcode會自動給你轉成下面的形式
@iboutlet weak var headerbgimageview: uiimageview!
/***/
ps:如果你在隱式解析可選型別沒有值的時候進行取值,會crash。和在沒有值的可選型別裡面拆包是一樣的。
!
的使用場景
1.強制對optional
值進行拆包(unwrap)
2.宣告隱式拆包變數,一般用於類中的屬性
其實!
和?
的問題是很坑的,不要看它僅僅是兩個符號,因為只要有乙個不小心,不注意,你會發現專案執行起來,會莫名的crash掉了,關鍵是debug模式也不是很方便定位錯誤型別。 自己整理一下關於 可選型別的相關使用,一是記錄和鞏固所學,而是希望會對大家有所幫助。 本文可能會有錯誤和不妥之處,還望提出,我會及時改正。
Swift中 和 的區別
1.常量和變數 swift語言中是用let來定義常量,並且要初始化。var來定義變數,在let或者var後面申明型別,冒號 空格,然後再加上型別名稱。2.optional 可選 變數 可選變數用於處理值缺失的情況,有點類似於oc中的nil,可以用於任何型別上,不僅僅是類,不過更加安全。swift是型...
php中 和「「的區別及使用
和 通常是php用來定義字串時使用。定義乙個字串最簡單的方法是使用單引號把它包圍起來。在php中想要表達乙個單引號,則需要使用 來進行轉義例 衍生下想要表達乙個 自身則需要使用兩個反斜線。例 在php官方文件中是這樣定義的 不像雙引號和heredoc語法結構,在單引號字串中的變數和特殊字元的轉義序列...
C C 中 和 的使用區別
剛剛,筆者編譯剛寫完的課程實驗時,編譯器報錯200 著實嚇了一跳。仔細一看,基本上全都是類似如下的錯誤提示,這才安心了。遇到這樣的錯誤,其實只需要乙個個把所使用的所有 替換成 運算子即可。不過這也著實浪費了我不少時間去乙個個改誒。qaq 下面,順便來說一下這兩個運算子在使用上的區別 明確一點,是指標...