本文系閱讀閱讀原章節後總結概括得出。由於需要我進行一定的概括提煉,如有不當之處歡迎讀者斧正。如果你對內容有任何疑問,歡迎共同交流討論。
建立字串變數有兩種寫法:String("something")
和"something"
,這兩種寫法效果一樣但背後的原理不同。"something"
是字串字面量,在前面的章節我們已經介紹過陣列字面量。
想通過字串字面量建立字串變數,比使用陣列更復雜一些。我們看一下StringLiteralConvertible
協議的定義:
public protocol StringLiteralConvertible : ExtendedGraphemeClusterLiteralConvertible {
typealias StringLiteralType
public init(stringLiteral value: Self.StringLiteralType)
}
public typealias StringLiteralType = String
複製程式碼
可見StringLiteralConvertible
協議繼承自ExtendedGraphemeClusterLiteralConvertible
協議:
public protocol ExtendedGraphemeClusterLiteralConvertible : UnicodeScalarLiteralConvertible {
typealias ExtendedGraphemeClusterLiteralType
public init(extendedGraphemeClusterLiteral value: Self.ExtendedGraphemeClusterLiteralType)
}
public typealias ExtendedGraphemeClusterType = String
複製程式碼
而ExtendedGraphemeClusterLiteralConvertible
協議又整合自UnicodeScalarLiteralConvertible
協議:
public protocol UnicodeScalarLiteralConvertible {
typealias UnicodeScalarLiteralType
public init(unicodeScalarLiteral value: Self.UnicodeScalarLiteralType)
}
public typealias UnicodeScalarType = String
複製程式碼
因此,要實現字串字面量就必須實現這三層協議棧中所有的方法:
extension Regex: StringLiteralConvertible {
public init(stringLiteral value: String) {
regexp = value
}
public init(extendedGraphemeClusterLiteral value: String) {
self = Regex(stringLiteral: value)
}
public init(unicodeScalarLiteral value: String) {
self = Regex(stringLiteral: value)
}
}
複製程式碼
除非我們需要做一些細粒度的管理,比如字串可能通過字形叢集或Unicode標量建立,否則就像上面這樣,直接使用字串版本的實現即可。
實現了StringLiteralConvertible
協議後,我們就可以這樣建立Regex
型別的變數:
let r: Regex = "^h..lo*!$"
複製程式碼
如果變數的型別已經確定,事情就更簡單了:
func findMatches(strings: [String], regex: Regex) -> [String] {
return strings.filter { regex.match($0) }
}
let matches = findMatches(["foo", "bar", "baz"], regex: "^b..")
print(matches) // 輸出結果:["bar", "baz"]
複製程式碼
觀察此前協議棧中三個協議的定義,他們都有一個型別別名:
typealias xxx
public typealias xxx = String
複製程式碼
因此預設情況下通過字串字面量建立的變數的型別都是String
。如果你需要人為指定這個型別(在特定場合下可能效能更好),你可以重新指派型別別名:
typealias StringLiteralType = StaticString
let what = "hello"
print(what is StaticString) // 輸出結果:true
print(what is String) // 輸出結果:false
複製程式碼