《Advanced Swift》第三章 可選值:讀書筆記 一、哨崗值 二、通過枚舉解決魔法數的問題 三、可選值概覽 四、強制解包的時機 五、隱式解包可選值

一、哨崗值

int ch;
while ((ch = getchar()) != EOF) {
  printf("Read character %c\n", ch);
}
printf("Reached end-of-file\n");

        像上面的EOF,這種東西被叫做哨崗值,其廣泛存在與c、C++、java之中。其存在有其合理性,但是卻很不合理,其混淆了正常值、需要一些潛規則知識等等,不合理因素。
        Tony Hoare 在 1965 年設計了 null 引用,他對此設計表示痛心疾首,並將這個問題稱爲 “價值 十億美元的錯誤”。

二、通過枚舉解決魔法數的問題

        上文中的哨崗值其實就是一個魔法數,大家都知道這是不好的。所以在Swift中,引入了可選值(通過枚舉、關聯值、泛型來實現)。

// 可選值的核心代碼
enum Optional<Wrapped> {
  case none
  case some(Wrapped)
}

// 由於可選值遵循了ExpressibleByNilLiteral協議,所以可是用nil來代替none

三、可選值概覽


var array = ["one", "two", "three", "four"]
// 檢查可選值是否爲 nil,如果不是 nil,便會解包可選值
// idx 的類型就是 Int (而不再是可 選值),並且 idx 也只在這個 if let 語句的作用域中有效
if let idx = array.firstIndex(of: "four") {
  array.remove(at: idx)
}

// while let 語句和 if let 非常相似,它表示當一個條件返回 nil 時便終止循環。
while let line = readLine() {
  print(line)
}

// 爲了解決if、while、switch解包後值的作用域問題,引入了guard語句
// 可選鏈
// ?? 運算符

// 在字符串插值中使用可選值
let bodyTemperature: Double? = 37.0
let bloodGlucose: Double? = nil
print(bodyTemperature) // Optional(37.0)
// 警告:表達式被隱式強制從 'Double?' 轉換爲 Any
print("Blood glucose level: \(bloodGlucose)") // Blood glucose level: nil // 警告:字符串插值將使用調試時的可選值描述,
// 請確認這確實是你想要做的。

infix operator ???: NilCoalescingPrecedence
public func ???<T>(optional: T?, defaultValue: @autoclosure () -> String) -> String
{
switch optional {
  case let value?: return String(describing: value)
  case nil: return defaultValue()
  }
}

print("Body temperature: \(bodyTemperature ??? "n/a")") // Body temperature: 37.0
print("Blood glucose level: \(bloodGlucose ??? "n/a")")
// Blood glucose level: n/a

可選值提供了map、flatMap、compactMap方法。

四、強制解包的時機

        當你能確定你的某個值不可能是 nil 時可以使用歎號,你應當會希望如果它意外是 nil 的話,程序應當直接掛掉。

// 提供!!運算符,用於強制解包時,能夠輸出友好的信息
infix operator !!
func !! <T>(wrapped: T?, failureText: @autoclosure () -> String) -> T { ifletx=wrapped{returnx}
fatalError(failureText())
}

let s = "foo"
let i = Int(s) !! "Expecting integer, got \"\(s)\""

五、隱式解包可選值

        強制解包會引發崩潰,但是隱式解包與強制解包類似,但是它依然存在。

  • 在使用從nib獲取的outlet時,此時一般使用隱式解包
  • 爲了與OC代碼兼容
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章