官术网_书友最值得收藏!

2.4 兩種特殊的基本數據類型

Swift語言中還支持兩種特殊的基本數據類型,分別是元組類型與可選值類型。元組在實際開發中十分常用,開發者使用元組可以創建出任意數據類型組合的自定義數據類型。而可選值類型是Swift語言的一大特點,通過可選值類型,Swift語言對數值為空進行了嚴格把控。

2.4.1 元組

元組是Swift語言中重要的數據類型之一,元組允許一些并不相關的類型進行自由組合成為新的集合類型。在Objective-C語言中并不支持元組這樣的數據類型,這在很多時候會給開發者帶來麻煩。類比生活中的一種情景,元組類型十分類似于日常生活中的套餐,現在各種服務業都有許多特色的套餐推出供顧客選擇,方便為顧客提供一站式服務。元組提供的就是這樣一種編程結構。試想一下,編程中會遇到這樣一種情形,一個商品有名字和價格,使用元組可以很好地對這種商品類型進行模擬,示例如下:

    //創建鋼筆元組類型,其中有兩種類型:字符串類型的名稱和整數類型的價格
    var pen:(name:String,price:Int) = ("鋼筆",2)

上面的代碼在創建元組類型的同時也將其中參數的名稱進行了指定,即名稱參數為name,價格參數為price,開發者可以使用這些參數名稱來獲取元組中各個參數的值,示例如下:

    //獲取pen變量名稱
    var name = pen.name
    //獲取pen變量價格
    var price = pen.price

開發者在創建元組時,也可以不指定元組中參數的名稱,元組會自動為每個參數分配下標,下標值將從0開始依次遞增,示例如下:

    //不指定參數名稱的元組
    var car:(String,Int) = ("奔馳",2000000)
    //通過下標來取得元組中各個組成元素的值
    var carName = car.0
    var carPrice = car.1

元組實例被創建后,開發者也可以通過指定的變量或者常量來分解它,示例如下:

    //不指定參數名稱的元組
    var car:(String,Int) = ("奔馳",2000000)
    //進行元組的分解
    var (theName,thePrice) = car
    //此時 theName變量被賦值為"奔馳" thePrice變量被賦值為2000000
    print(theName,thePrice)

上面的代碼將元組實例car中的各個組成元素分解到具體變量,有一點讀者需要注意,分解后的變量必須與元組中的元素一一對應(個數相等),否則編譯器就會報錯。代碼中使用的print()函數為打印輸出函數,print()函數可以接收多個參數,將其以逗號分隔即可。有些時候,開發者可能并不需要獲取某個元組實例中所有元素的值,這種情況下,開發者也可以將某些不需要獲取的元素使用匿名的方式來接收,示例如下:

    //不指定參數名稱的元組
    var car:(String,Int) = ("奔馳",2000000)
    //進行元組的分解 將Int型參數進行匿名
    var (theName,_) = car
    //此時 theName變量被賦值為"奔馳"
    print(theName)

在Swift語言中,常常使用符號“_”來表示匿名的概念,因此“_”也被稱為匿名標識符。上面的代碼實際上只分解出了元組car中的第一個元素(String類型)。

提示

元組雖然使用起來十分方便,然而其只適用于簡單數據的組合,對于結構復雜的數據,要采用結構體或者類來實現。

2.4.2 可選值類型

可選值類型(Optional類型)是Swift語言特有的一種類型。首先,Swift語言是一種十分強調類型安全的語言,開發者在使用到某個變量時,編譯器會盡最大可能保證此變量的類型和值的明確性,保證減少編程中的不可控因素。然而在實際編程中,無論任何類型的變量都會遇到值為空的情況,在Objective-C語言中并沒有機制來專門監控和管理為空值的變量,程序的運行安全性全部靠開發者手動控制。Swift語言中提供了一種包裝的方式來對普通類型進行Optional包裝,實現對空值情況的監控。

在Swift語言中,如果使用了一個沒有進行賦值的變量,程序是會直接報錯停止運行的。讀者可能會想,如果一個變量在聲明的時候沒有賦初值,在后面的程序運行中就有可能被進行賦值,那么在使用時,應該怎么做呢?在Objective-C中,這個問題很好解決,只需要使用的時候判斷一下此變量是否為nil即可,那么在Swift中是否也可以這樣做呢?使用如下代碼來進行試驗:

編寫上面的代碼后,可以看到Xcode工具依然拋出了一個錯誤提示,其實在Swift語言中普通的類型是不允許為nil的,當然也就不可以與nil進行比較運算,這種機制極大地減小了代碼的不可控性。如果一個變量在邏輯上可能為nil,則開發者需要將其包裝為Optional類型,改寫上面的代碼如下:

此時代碼就可以正常運行了,分析上面的代碼,在聲明obj變量的時候,這里將其聲明成了String?類型,在普通類型后面添加符號“?”,即可以將普通類型包裝為Optional類型。

Optional類型不會獨立存在,總是會附著于某個具體的數據類型之上,具體的數據類型可以是基本數據類型,可以是結構體,也可以是類等。Optional類型只有兩種值,讀者可以將其理解為:


· 如果其附著類型對應的量值有具體的值,則其為具體值的包裝。

· 如果其附著類型對應的量值沒有具體的值,則其為nil。


舉個例子,將Int類型的變量a進行Optional包裝,則此時a的類型為Int?,如果對a進行了賦值,則可以通過拆包的方式獲取a的Int類型值,如果沒有對a進行賦值則a為nil。

提示

Optional類型中的nil讀者也可以理解為一種值,其表示空。

Optional類型是對普通類型的一種包裝,因此在使用的時候也需要對其進行拆包操作,拆包將使用到Swift中的操作符“!”。“?”與“!”這兩個操作符是很多Swift語言初學者的噩夢,如果讀者理解了Optional類型,那么對這兩個操作符的理解和使用也將容易許多。首先需要注意,“?”符號可以出現在類型后面,也可以出現在實例后面,如果出現在類型后面,其代表的是此類型對應的Optional類型,如果出現在實例名后面,則代表的是可選鏈的調用,后面章節會有詳細介紹。“!”符號同樣也可以出現在類型后面與實例后面,它出現在類型后面代表的是一種隱式解析的語法結構,后面章節會有介紹;出現在實例后面代表的是對Optional類型實例的拆包操作。示例如下:

    //聲明obj為String?類型
    var obj:String? = "HS"
    //進行拆包操作
    obj!

讀者需要注意,在使用“!”進行Optional值的拆包操作時,必須保證要拆包的值不為nil,否則程序運行會出錯。可以在拆包前使用if語句進行安全判斷,示例如下:

上面代碼演示的編程結構在實際應用中十分廣泛,因此Swift語言還提供了一種if-let語法結構來進行Optional類型值的綁定操作,可以將上面的結構改寫如下:

上面的代碼可以這樣理解:如果obj有值,則if-let結構將創建一個臨時常量tmp來接收obj拆包后的值,并且執行if為真時所對應的代碼塊,在執行的代碼塊中,開發者可以直接使用拆包后的obj值tmp。如果obj為nil,就會進入if為假的代碼塊中,開發者可以在else代碼塊中將obj重新賦值使用。這種if-let結構實際上完成了判斷、拆包、綁定拆包后的值到臨時常量3個過程。

if-let結構中也可以同時進行多個Optional類型值的綁定,之間用逗號隔開,示例如下:

在同時進行多個Optional類型值的綁定時,只有所有Optional值都不為nil,綁定才會成功,代碼執行才會進入if為真的代碼塊中。如果開發者需要在if語句的判斷中添加更多業務邏輯,可以通過追加子句的方式來實現,示例如下:

上面的代碼在obj1不為nil、obj2不為nil并且obj1所對應的拆包值小于obj2對應的拆包值的時候才會進入if判斷為真的代碼塊,即打印綁定的tmp1與tmp2的值。

Optional值在Swift語言編程中的應用十分靈活,在以后的編程練習中,讀者會逐步體會其中的奧妙。

主站蜘蛛池模板: 靖西县| 修武县| 西平县| 兴安县| 独山县| 黎城县| 临颍县| 分宜县| 景德镇市| 福州市| 偃师市| 望奎县| 鸡西市| 将乐县| 泰州市| 江山市| 兴海县| 邻水| 龙口市| 绿春县| 灵宝市| 博客| 合山市| 调兵山市| 施甸县| 綦江县| 临澧县| 乐清市| 丹寨县| 鄂尔多斯市| 水城县| 吉林市| 长宁区| 定安县| 顺昌县| 皮山县| 连城县| 巴青县| 祥云县| 泸定县| 南部县|