本文系阅读阅读原章节后总结概括得出。由于需要我进行一定的概括提炼,如有不当之处欢迎读者斧正。如果你对内容有任何疑问,欢迎共同交流讨论。
创建字符串变量有两种写法: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