列舉
enum Direction {
case north, south, east, west
}
複製程式碼
- 關聯值
- 有時會將列舉的成員值跟其他型別的關聯儲存在一起,會非常有用
enum Score {
case points(Int)
case grade(Character)
}
var score = Score.points(96)
score = .grade("A")
switch score {
case let .points(i):
print("points", i)
case let .grade(i):
print("grade", i)
}
複製程式碼
比如在使用者密碼的設定
enum Password {
case number(Int, Int, Int, Int)
case gesture(String) // 如果是手勢,你不知道他到底是怎麼畫的,畫了幾個,用 number 存會麻煩一點
}
複製程式碼
- 原始值(rawValue)
- 列舉成員可以使用相同型別的預設值預先關聯,這個預設值叫做:原始值
- 隱式原始值
- 如果列舉的原始值是 Int、String,Swift 會自動分配原始值
- 遞迴列舉
enum Grade: String {
case perfect = "A"
case great = "B"
case good = "C"
case bad = "D"
}
複製程式碼
遞迴列舉:
enum ArithExpr {
case number(Int)
indirect case sum(ArithExpr, ArithExpr)
indirect case difference(ArithExpr, ArithExpr)
}
複製程式碼
MemoryLayout
- 可以使用 MemoryLayout 獲取資料型別佔用的記憶體大小
// 型別實際使用的大小
MemoryLayout<Int>.size
//
// 型別分配的記憶體空間大小
MemoryLayout<Int>.stride
// 型別的記憶體對齊
MemoryLayout<Int>.alignment
let age = 10
MemoryLayout.size(ofValue: age)
MemoryLayout.stride(ofValue: age)
MemoryLayout.alignment(ofValue: age)
複製程式碼
可選項(Optional)
- 可選項,一般也叫可選型別,它允許將值設定為 nil
- 在型別名稱後面加個問號?來定義一個可選項
- 可選項繫結
- 可以使用可選項繫結來判斷可選項是否包含值
- 如果包含就自動解包,把值賦值給一個臨時的常量或者變數,並返回 true,否則返加 false
if let number = Int("123") {
} else {
}
複製程式碼
- 空合併運算子
- a ?? b
- a 是可選項
- b 跟 a 的儲存型別必須相同,可以是可選,也可以是不可選
- 如果 b 不是可選項,返回 a 時會自動解包(這一點要注意,就是返回值是不是可選主要看後面的是不是可選項)
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throw -> T?) rethrows -> T?
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throw -> T) rethrows -> T
複製程式碼
if let c = a ?? b { }
等於
if a != nil || b != nil { }
複製程式碼
guard 語句
- 一般用來“提前退出”
- 當使用 guard 語句進行可選項繫結時,繫結的常量,變數也能在外層作用域中使用
guard 條件 else {
退出當前作用域
}
複製程式碼
隱式解包
- 在某些情況下,可選項一旦敲定值之後,就會一直擁有值
- 在這種情況下,可以去掉檢查,也不必每次訪問的時候都進行解包,因為它能確定每次訪問的時候都有值
- 可以在型別後面加個感嘆號 ! 定義一個隱式解包的可選項
// 隱式解包的可選項
// 這個型別基本上沒啥用
var num1: Int! = 10
num1 = nil
print(num1)
這個地方發列印 nil,不會發生崩潰
複製程式碼
字串插值
- 可選項在字串插值或者直接列印時,編譯器會發出警告
- 至少有3種方法消除警告
var age: Int? = 10
// String interpolation produces a debug description for an optional value; did you mean to make this explicit?
print("My age is \(age)")
// 解決方式
print("My age is \(age!)")
print("My age is \(String(describing: age))")
print("My age is \(age ?? 0)")
複製程式碼
多重可選項
- 可以利用 frame variable -R 檢視區別
var num1: Int? = nil
var num2: Int?? = 10
var num3: Int?? = nil
print(num2 == num3) // false
print(num1 == num3) // false
(num2 ?? 1) ?? 2 // 2
(num3 ?? 1) ?? 2 // 1
frame variable -R 變成了
(Swift.Optional<Swift.Int>) num1 = none {
some = {
_value = 0
}
}
(Swift.Optional<Swift.Optional<Swift.Int>>) num2 = some {
some = some {
some = {
_value = 10
}
}
}
(Swift.Optional<Swift.Optional<Swift.Int>>) num3 = none {
some = some {
some = {
_value = 0
}
}
}
複製程式碼