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

版本記錄

版本號 時間
V1.0 2017.07.23

前言

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

可選值

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

  • 有值,等于x
  • 沒有值

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

下面看一個例子,swift中的String類型可以轉化為整形,如下所示。

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

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

1. if語句及強制解析

你可以使用if語句來判斷一個可選是否包含值,如果可選類型有值,結果就是true,如果沒有值就是false,當你確定可選類型確實包含值之后,你可以在可選的名字后面加一個感嘆號!來獲取值,這個驚嘆號表示我知道這個可選值有值,請使用它,這被稱為可選值的強制解析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")
}


下面看輸出結果

123 has an integer value of 123 

2. 可選綁定

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

下面看代碼。

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包含一個值,創建一個叫做actualNumber的新常量,并將可選包含的值賦給它。如果轉換成功則走if的第一個分支,不成功就走第二個分支。

3. nil值

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

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

serviceResponseCode = nil
//serviceResponseCode現在不包含值

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

如果你聲明一個可選常量或者變量但是沒有賦值,它們會自動被設置為nil

var surveyAnswer : String ?
//surveyAnswer被自動設置為nil

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

4. 隱式解析可選類型

有時候在程序架構中,第一次被賦值之后,可以確定一個可選類型總會有值,在這種情況下,每次都要判斷和解析可選值是非常低效的,因為可以確定它總會有值。這種類型的可選狀態被定義為隱士解析可選類型implicitly unwrapped optionals,把想要用作可選的類型的后面的問號String?改成String!來聲明一個隱式解析可選類型。

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

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

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

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

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

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


斷言

可選類型可以讓你判斷值是否存在,你可以在代碼中優雅的處理值缺失的情況,然而,在某些情況下,如果值缺失或者不滿足特定條件,你的代碼可能沒辦法執行,這時,你可以在代碼中,觸發一個斷言assertion來結束代碼運行并通過調試找到值缺失的原因。

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不空就繼續往下執行,如果為空就拋出異常@"Could not find constraint %@", constraint

下面我們繼續看一下swift中的斷言。

1. 使用斷言進行調試

斷言會在運行時判斷一個邏輯條件是否為true,你可以使用斷言來保證在運行其他代碼之前,某些重要的條件已經被滿足了。如果條件為true,代碼運行會繼續運行,如果條件為false,代碼運行停止,應用也停止。

你可以使用全局assert函數寫一個斷言,看下面例子。

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

這里由于age > 0false,不會往下執行,會拋出斷言異常。

2. 何時使用斷言

當條件可能為假時使用斷言,但是最終一定要保證條件為真,這樣你的代碼才能繼續運行,使用一下情形。

  • 整數類型的下標索引被傳入一個自定義下標腳本實現,但是下標索引值可能太大或者太小。
  • 函數需要傳入一個值,但是非法的值可能導致函數不能正常運行。
  • 一個可選值現在是nil,但是后面運行需要一個非nil值。

運算符

運算符是檢查、改變、合并值的特殊符號或短語。swift支持大部分標準C語言的運算符,且改進很多特性減少常規編碼錯誤。但是區別于C語言,在swift中你可以對浮點數進行取余運算%,swift還提供了C語言沒有的表達兩數之間值的區間運算符a..<ba...b,這方便我們表達一個區間內的數值。

1. 運算符的分類

運算數按照操作數的個數,可以分為一元、二元和三元運算符。

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

后記

未完,待續~~

風景
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容