Swift學習(五): 枚舉(基本用法,關聯值,原始值,遞歸枚舉,MemoryLayout,可選項,強制解包,可選項綁定,空合併運算符??,隱式解包,多重可選項,guard)

枚舉的基本用法

  等價於 =>>

使用: 

 

 

-------------------------------------------------------------------------------------------------------------------------------

關聯值(Associated Values)

有時會將枚舉的成員值跟其他類型的關聯存儲在一起,會非常有用

  • 必要時let也可以改爲var

 

  • 關聯值舉例

       

-------------------------------------------------------------------------------------------------------------------------------

原始值(Raw Values)

-------------------------------------------------------------------------------------------------------------------------------

隱式原始值(Implicitly Assigned Raw Values)

-------------------------------------------------------------------------------------------------------------------------------

遞歸枚舉(Recursive Enumeration)

枚舉裏的枚舉類型中又調用了枚舉,就是遞歸枚舉,注意要在前面加上indirect,否則報錯

  等價於==>

 

     結果是 5 + 4 - 2 = 7

-------------------------------------------------------------------------------------------------------------------------------

MemoryLayout

可以使用MemoryLayout來獲取數據類型佔用的內存大小

 

這裏要注意pwd爲33是因爲要多出來一個字節來區分other和上面的number。

.stride : 分配佔用的空間大小,必須是內存對齊參數alignment的整數倍,所以是40

.alignment : 內存對齊參數

.size : 實際用到的空間大小,這裏的33表示number(Int, Int, Int, Int)中的Int每個佔8個字節,總共佔32個,other佔一個字節,加起來33個字節。

  這個佔用四個字節

 

這裏要說一下關聯值和原始值:

number(Int, Int, Int, Int) : 屬於關聯值,將傳進來的關聯值存儲到枚舉變量裏面,因爲關聯值由外部傳入,可以任意變化,需要存儲,而原始值固定默認的,不可改變

而.other : 屬於原始值,不會存儲到枚舉變量內存裏面的

-------------------------------------------------------------------------------------------------------------------------------

可選項(Optional)

注意:Swift裏一般的值是不可以直接賦值爲nil的,但是可選類型的值可以。

  • 可選項,一般也叫可選類型,它允許將值設置爲nil
  • 在類型名稱後面加個問號?來定義一個可選項

  -> int ? 表示返回值可以爲Int也可以爲nil

-------------------------------------------------------------------------------------------------------------------------------

強制解包

  • 可選項是對其他類型的一層包裝,可以將它理解爲一個盒子
  • 如果爲nil,那麼它是個空盒子
  • 如果不爲nil,那麼盒子裏裝的是:被包裝類型的數據

  • 如果要從可選項中取出被包裝的數據(將盒子裏的東西取出來),需要使用!進行強制解包
var age : Int? = 10
var ageInt : Int = age!
ageInt += 10
  • 如果對值爲nil的可選項(空盒子)進行強制解包,將會產生運行時錯誤

  • 判斷可選項是否包含值

-------------------------------------------------------------------------------------------------------------------------------

可選項綁定(Optional Binding)

  • 可以使用可選項綁定來判斷可選項是否包含值
  • 如果包含就自動解包,把值給一個臨時的常量(let)或者變量(var), 並返回true,否則返回false

  備註:Season(rawValue: 6)是指取原始值爲6的枚舉,2就會取到summer

  • 等價寫法

 注意:可選項綁定的並列條件不能用 && ,可以用,

 

-------------------------------------------------------------------------------------------------------------------------------

while循環中使用可選項綁定

-------------------------------------------------------------------------------------------------------------------------------

空合併運算符??(Nil -Coalescing Operator)

定義:

  • a ?? b 
  1. a 是可選項
  2. b 是可選項 或者 不是可選項
  3. b 跟 a 的存儲類型必須相同
  4. 如果 a 不爲nil,就返回 a
  5. 如果 a 爲nil,就返回 b
  6. 如果 b 不是可選項,返回 a 時會自動解包
  • 舉例:

  • 多個 ?? 一起使用

 不可以寫成 let c = a ?? 3 ?? b,因爲 ?? 左邊必須是可選型,不能是3

-------------------------------------------------------------------------------------------------------------------------------

空合併運算符??跟 if let配合使用

  • if語句實現登陸

   標註:if let tmp = info["username"]中的tmp作用域只在它大括號裏,不能作用在括號外,所以要定義一個外部常量,來獲取這個值

注意:字典類型的取值比如info["username"]這種字典類型的取值爲可選類型(?),因爲如果key值寫錯,取到的值就爲nil,這時就要用到可選類型,但是數組當取-1這種超出取值範圍的錯誤值的時候,編譯器會直接報錯,不會自動轉爲可選值

-------------------------------------------------------------------------------------------------------------------------------

guard語句

  • 當guard語句的條件爲false時,就會執行大括號裏的代碼
  • 當guard語句的條件爲true, 就會跳過guard語句
  • guard語句特別適合用來"提前退出"

  • 使用guard語句進行可選項綁定時,綁定的常量(let)和變量(var)也能在外層作用域中使用

-------------------------------------------------------------------------------------------------------------------------------

隱式解包(Implicitly unWrapped Optional)

  • 在某些情況下,可選項一旦被設定值之後,就會一直擁有值
  • 在這種情況下,可以去掉檢查,也不必每次訪問的時候都進行解包,因爲它能確定每次訪問的時候都有值 
  •  可以在類型後面加個感嘆號 ! 定義一個隱式解包的可選項
let num1: Int! = 10
let num2: Int = num1
if num2 != nil {
   print(num2 + 6)
}
if let num3 = num1 {
   print(num3)
}

注意:隱式解包的默認值不能爲nil,否則會報錯

-------------------------------------------------------------------------------------------------------------------------------

字符串插值

  • 可選項在字符串插值或者直接打印時,編譯器會發出警告

  • 至少有3種方法消除警告

-------------------------------------------------------------------------------------------------------------------------------

多重可選項

  =>可轉化成結構圖:             

 我們可以看出num2等於num3

  • 可以使用lldb指令 frame variable -R 或者 fr  v -R查看區別

 

-------------------------------------------------------------------------------------------------------------------------------

多重可選項(nil情況)

=>可轉化成結構圖:

 

這裏可以看出num2與num3不同:

  • 可以使用lldb指令 frame variable -R 或者 fr  v -R查看區別

下圖我們可以看出:

表達式1 :num2不爲nil,表達式轉化爲num1 ?? 2, num1位nil,最終得到2

表達式2 :num3爲nil,表達式轉化爲 1 ?? 2,最終得到1。

提醒一下,可能有人認爲num1 和num3同爲nil應該相同,這是錯的,因爲兩者類型不同,num1爲Int?, num3 爲Int??

var n = num3!! :這表示雙重解包,n爲Int類型。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章