作者:Erica Sadun,原文連結,原文日期:2018-12-12 譯者:RocZhang;校對:numbbbbb,pmst;定稿:Forelax
感謝提案 SE-0228,讓我們能夠精確控制字串插值的列印方式。感謝 Brent 帶給我們這個非常棒的功能。讓我來分享一些例子。
回想一下在我們要列印可選值的時候,會這樣寫:
"There's \(value1) and \(value2)"
複製程式碼
但這樣寫會立即得到一個警告:
我們可以點選修復按鈕來消除這些警告,得到如下的程式碼。但我們仍然會看到一個類似於這樣的輸出:“There’s Optional(23) and nil”。
"There's \(String(describing: value1)) and \(String(describing: value2))"
複製程式碼
現在我們可以通過下面這種方式去掉輸出中的“Optional”,直接列印出“There’s 23 and nil”:
extension String.StringInterpolation {
/// 提供 `Optional` 字串插值
/// 而不必強制使用 `String(describing:)`
public mutating func appendInterpolation(_ value: T?, default defaultValue: String) {
if let value = value {
appendInterpolation(value)
} else {
appendLiteral(defaultValue)
}
}
}
// There's 23 and nil
"There's \(value1, default: "nil") and \(value2, default: "nil")"
複製程式碼
我們也可以建立一組樣式,從而使可選值能夠保持一致的輸出展示方式:
extension String.StringInterpolation {
/// 可選值插值樣式
public enum OptionalStyle {
/// 有值和沒有值兩種情況下都包含單詞 `Optional`
case descriptive
/// 有值和沒有值兩種情況下都去除單詞 `Optional`
case stripped
/// 使用系統的插值方式,在有值時包含單詞 `Optional`,沒有值時則不包含
case `default`
}
/// 使用提供的 `optStyle` 樣式來插入可選值
public mutating func appendInterpolation(_ value: T?, optStyle style: String.StringInterpolation.OptionalStyle) {
switch style {
// 有值和沒有值兩種情況下都包含單詞 `Optional`
case .descriptive:
if value == nil {
appendLiteral("Optional(nil)")
} else {
appendLiteral(String(describing: value))
}
// 有值和沒有值兩種情況下都去除單詞 `Optional`
case .stripped:
if let value = value {
appendInterpolation(value)
} else {
appendLiteral("nil")
}
// 使用系統的插值方式,在有值時包含單詞 `Optional`,沒有值時則不包含
default:
appendLiteral(String(describing: value))
}
}
/// 使用 `stripped` 樣式來對可選值進行插值
/// 有值和沒有值兩種情況下都省略單詞 `Optional`
public mutating func appendInterpolation(describing value: T?) {
appendInterpolation(value, optStyle: .stripped)
}
}
// "There's Optional(23) and nil"
"There's \(value1, optStyle: .default) and \(value2, optStyle: .default)"
// "There's Optional(23) and Optional(nil)"
"There's \(value1, optStyle: .descriptive) and \(value2, optStyle: .descriptive)"
// "There's 23 and nil"
"There's \(describing: value1) and \(describing: value2)"
複製程式碼
插值不僅僅用於調整可選值的輸出方式,在其他方面也很有用。比如你想控制輸出是否帶有特定的字元,就不需要寫一個帶有空字串的三元表示式:
// 成功時包含(感謝 Nate Cook)
extension String.StringInterpolation {
/// 只有 `condition` 的返回值為 `true` 才進行插值
mutating func appendInterpolation(if condition: @autoclosure () -> Bool, _ literal: StringLiteralType) {
guard condition() else { return }
appendLiteral(literal)
}
}
// 舊寫法
"Cheese Sandwich \(isStarred ? "(*)" : "")"
// 新寫法
"Cheese Sandwich \(if: isStarred, "(*)")"
複製程式碼
我們還可以用字串插值來做更多有趣的事情。
本文由 SwiftGG 翻譯組翻譯,已經獲得作者翻譯授權,最新文章請訪問 swift.gg。