swift簡單總結(jié)(九)—— 可選值和斷言

版本記錄

版本號(hào) 時(shí)間
V1.0 2017.07.23

前言

我是swift2.0的時(shí)候開始接觸的,記得那時(shí)候還不是很穩(wěn)定,公司的項(xiàng)目也都是用oc做的,并不對(duì)swift很重視,我自己學(xué)了一段時(shí)間,到現(xiàn)在swift3.0+已經(jīng)出來了,自己平時(shí)也不寫,忘記的也差不多了,正好項(xiàng)目這段時(shí)間已經(jīng)上線了,不是很忙,我就可以每天總結(jié)一點(diǎn)了,希望對(duì)自己對(duì)大家有所幫助。在總結(jié)的時(shí)候我會(huì)對(duì)比oc進(jìn)行說明,有代碼的我會(huì)給出相關(guān)比對(duì)代碼。
1. swift簡單總結(jié)(一)—— 數(shù)據(jù)簡單值和類型轉(zhuǎn)換
2. swift簡單總結(jié)(二)—— 簡單值和控制流
3. swift簡單總結(jié)(三)—— 循環(huán)控制和函數(shù)
4. swift簡單總結(jié)(四)—— 函數(shù)和類
5. swift簡單總結(jié)(五)—— 枚舉和結(jié)構(gòu)體
6. swift簡單總結(jié)(六)—— 協(xié)議擴(kuò)展與泛型
7. swift簡單總結(jié)(七)—— 數(shù)據(jù)類型
8. swift簡單總結(jié)(八)—— 別名、布爾值與元組

可選值

可選類型(optional)來處理值可能缺失的情況,可選類型表示:

  • 有值,等于x
  • 沒有值

注意occ中并米喲可選類型這個(gè)概念,對(duì)于oc來說,對(duì)象可以有也可以為nil,nil就表示缺少一個(gè)合法的對(duì)象,然而,這只對(duì)對(duì)象起作用,對(duì)于結(jié)構(gòu)體,基于C類型或者枚舉類型不起作用。對(duì)于這些類型,oc方法會(huì)返回一個(gè)特殊值,例如NSNotFound來暗示缺值,這種方法假設(shè)方法的調(diào)用者知道并記得對(duì)特殊值進(jìn)行判斷,然而, swift的可選類型可以讓你暗示任意類型的值缺失,并不需要一個(gè)特殊值。

下面看一個(gè)例子,swift中的String類型可以轉(zhuǎn)化為整形,如下所示。

let str = "123";
let value = (str as NSString) .integerValue;
print(value)

但是有的字符串是不能轉(zhuǎn)化為整形的,比如"Hello world",因此轉(zhuǎn)化為整形可能會(huì)失敗,所以會(huì)返回一個(gè)可選類型(optional) Int,而不是一個(gè)Int,一個(gè)可選的Int被寫作Int?而不是Int

1. if語句及強(qiáng)制解析

你可以使用if語句來判斷一個(gè)可選是否包含值,如果可選類型有值,結(jié)果就是true,如果沒有值就是false,當(dāng)你確定可選類型確實(shí)包含值之后,你可以在可選的名字后面加一個(gè)感嘆號(hào)!來獲取值,這個(gè)驚嘆號(hào)表示我知道這個(gè)可選值有值,請(qǐng)使用它,這被稱為可選值的強(qiáng)制解析forced unwrapping。

下面看一下代碼。

let str = "123";
let value = (str as NSString) .integerValue;

if value != nil {
    print("\(str) has an integer value of \(value) ")
}
else {
    print("\(str) couldn't be converted to an integer")
}


下面看輸出結(jié)果

123 has an integer value of 123 

2. 可選綁定

使用可選綁定optional binding來判斷可選類型是否包含值,如果包含就把值賦給一個(gè)臨時(shí)常量或者變量,可選綁定可以用ifwhile語句中來對(duì)可選類型的值進(jìn)行判斷并把值賦給一個(gè)常量或者變量。

下面看代碼。

if let actualNumber = str.toValue() {
    print("\(str) has an integer value of \(actualNumber) ")
}
else {
    print("\(str) couldn't be converted to an integer")
}

這里可以理解: str.toValue()返回的可選Int包含一個(gè)值,創(chuàng)建一個(gè)叫做actualNumber的新常量,并將可選包含的值賦給它。如果轉(zhuǎn)換成功則走if的第一個(gè)分支,不成功就走第二個(gè)分支。

3. nil值

swift中也有nil值,你可以給可選變量賦值為nil來表示它沒有值。

var serviceResponseCode : Int ? = 404
//serviceResponseCode包含一個(gè)可選的Int 值404

serviceResponseCode = nil
//serviceResponseCode現(xiàn)在不包含值

注意nil不能用于非可選常量和變量,如果你的代碼中有常量或者變量需要處理值缺失的情況,請(qǐng)把它們聲明成對(duì)應(yīng)的可選類型。

如果你聲明一個(gè)可選常量或者變量但是沒有賦值,它們會(huì)自動(dòng)被設(shè)置為nil。

var surveyAnswer : String ?
//surveyAnswer被自動(dòng)設(shè)置為nil

注意swift中的niloc中的nil并不一樣,在oc中,nil是一個(gè)指向不存在對(duì)象的指針,在swift中,nil不是一個(gè)指針,它是一個(gè)確定的值,用來表示值確實(shí),任何類型的可選狀態(tài)都可以設(shè)置為nil,不只是對(duì)象類型。

4. 隱式解析可選類型

有時(shí)候在程序架構(gòu)中,第一次被賦值之后,可以確定一個(gè)可選類型總會(huì)有值,在這種情況下,每次都要判斷和解析可選值是非常低效的,因?yàn)榭梢源_定它總會(huì)有值。這種類型的可選狀態(tài)被定義為隱士解析可選類型implicitly unwrapped optionals,把想要用作可選的類型的后面的問號(hào)String?改成String!來聲明一個(gè)隱式解析可選類型。

當(dāng)可選類型被第一次賦值之后就可以確定之后一直有值的時(shí)候,隱式解析可選類型非常有用,隱式解析可選類型主要被用在swift中類的構(gòu)造過程中。

一個(gè)隱式解析可選類型其實(shí)就是一個(gè)普通的可選類型,但是可以被當(dāng)做非可選類來使用,并不需要每次都使用解析來獲取可選值。

下面的例子展示了可選類型String和隱式解析可選類型String之間的區(qū)別。

let possibleString : String? = "An optional string."
print(possibleString)

let assumedString : String! = "An implicitly unwrapped optional string"
print(assumedString)

注意:如果一個(gè)變量之后可能會(huì)變成nil的話請(qǐng)不要使用隱式解析可選類型,如果你需要在變量的生命周期中判斷是否是nil的話,請(qǐng)使用普通可選類型。


斷言

可選類型可以讓你判斷值是否存在,你可以在代碼中優(yōu)雅的處理值缺失的情況,然而,在某些情況下,如果值缺失或者不滿足特定條件,你的代碼可能沒辦法執(zhí)行,這時(shí),你可以在代碼中,觸發(fā)一個(gè)斷言assertion來結(jié)束代碼運(yùn)行并通過調(diào)試找到值缺失的原因。

oc中也有斷言,我們可以先看一下Masonry中也有斷言。

- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint 
{
    NSUInteger index = [self.childConstraints indexOfObject:constraint];
    NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
    [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
}


這里的斷言的意思就是:如果index不空就繼續(xù)往下執(zhí)行,如果為空就拋出異常@"Could not find constraint %@", constraint

下面我們繼續(xù)看一下swift中的斷言。

1. 使用斷言進(jìn)行調(diào)試

斷言會(huì)在運(yùn)行時(shí)判斷一個(gè)邏輯條件是否為true,你可以使用斷言來保證在運(yùn)行其他代碼之前,某些重要的條件已經(jīng)被滿足了。如果條件為true,代碼運(yùn)行會(huì)繼續(xù)運(yùn)行,如果條件為false,代碼運(yùn)行停止,應(yīng)用也停止。

你可以使用全局assert函數(shù)寫一個(gè)斷言,看下面例子。

let age = -10
assert(age > 0, "A person age must not be less than zero")

這里由于age > 0false,不會(huì)往下執(zhí)行,會(huì)拋出斷言異常。

2. 何時(shí)使用斷言

當(dāng)條件可能為假時(shí)使用斷言,但是最終一定要保證條件為真,這樣你的代碼才能繼續(xù)運(yùn)行,使用一下情形。

  • 整數(shù)類型的下標(biāo)索引被傳入一個(gè)自定義下標(biāo)腳本實(shí)現(xiàn),但是下標(biāo)索引值可能太大或者太小。
  • 函數(shù)需要傳入一個(gè)值,但是非法的值可能導(dǎo)致函數(shù)不能正常運(yùn)行。
  • 一個(gè)可選值現(xiàn)在是nil,但是后面運(yùn)行需要一個(gè)非nil值。

運(yùn)算符

運(yùn)算符是檢查、改變、合并值的特殊符號(hào)或短語。swift支持大部分標(biāo)準(zhǔn)C語言的運(yùn)算符,且改進(jìn)很多特性減少常規(guī)編碼錯(cuò)誤。但是區(qū)別于C語言,在swift中你可以對(duì)浮點(diǎn)數(shù)進(jìn)行取余運(yùn)算%,swift還提供了C語言沒有的表達(dá)兩數(shù)之間值的區(qū)間運(yùn)算符a..<ba...b,這方便我們表達(dá)一個(gè)區(qū)間內(nèi)的數(shù)值。

1. 運(yùn)算符的分類

運(yùn)算數(shù)按照操作數(shù)的個(gè)數(shù),可以分為一元、二元和三元運(yùn)算符。

  • 一元運(yùn)算符:一元運(yùn)算符對(duì)單一操作對(duì)象操作,如-a,一元運(yùn)算符分為前置運(yùn)算符和后置運(yùn)算符,前置運(yùn)算符如!a,后置運(yùn)算符如i++。
  • 二元運(yùn)算符:二元運(yùn)算符操作兩個(gè)操作對(duì)象,如2 + 3,是中置的。
  • 三元運(yùn)算符:操作三個(gè)操作對(duì)象,和C語言一樣,swift只有一個(gè)三元運(yùn)算符,就是三目運(yùn)算符a ? b : c。

后記

未完,待續(xù)~~

風(fēng)景
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容