Swift: 字符串开始(with:) vs hasPrefix
Swift: String starts(with:) vs hasPrefix
String.hasPrefix
(or [NSString hasPrefix]
) was always part of Foundation. However, I just noticed that now we also have starts(with:)
.
此方法来自 Sequence
,但它也适用于 String
。
我的问题是,我应该选择哪一个?有什么性能方面的考虑吗?我从 Objective-C 天开始就习惯了 hasPrefix
,但是 starts(with:)
更直观并且适用于其他序列。
String.hasPrefix()
在 StringLegacy.swift 中实现为
extension String {
public func hasPrefix(_ prefix: String) -> Bool {
if _fastPath(self._guts.isNFCFastUTF8 && prefix._guts.isNFCFastUTF8) {
guard prefix._guts.count <= self._guts.count else { return false }
return prefix._guts.withFastUTF8 { nfcPrefix in
let prefixEnd = nfcPrefix.count
return self._guts.withFastUTF8(range: 0..<prefixEnd) { nfcSlicedSelf in
return _binaryCompare(nfcSlicedSelf, nfcPrefix) == 0
}
}
}
return starts(with: prefix)
}
}
这意味着(如果我理解正确的话):如果字符串和候选前缀都使用基于 UTF-8 的存储,那么将直接比较 UTF-8 字节。否则它会退回到 starts(with:)
并进行基于 Character
的比较。
所以结果没有区别,但是 hasPrefix()
针对原生 Swift 字符串进行了优化。
注意:这是来自master(Swift5)的分支,早期版本情况可能有所不同。
String.hasPrefix
(or [NSString hasPrefix]
) was always part of Foundation. However, I just noticed that now we also have starts(with:)
.
此方法来自 Sequence
,但它也适用于 String
。
我的问题是,我应该选择哪一个?有什么性能方面的考虑吗?我从 Objective-C 天开始就习惯了 hasPrefix
,但是 starts(with:)
更直观并且适用于其他序列。
String.hasPrefix()
在 StringLegacy.swift 中实现为
extension String {
public func hasPrefix(_ prefix: String) -> Bool {
if _fastPath(self._guts.isNFCFastUTF8 && prefix._guts.isNFCFastUTF8) {
guard prefix._guts.count <= self._guts.count else { return false }
return prefix._guts.withFastUTF8 { nfcPrefix in
let prefixEnd = nfcPrefix.count
return self._guts.withFastUTF8(range: 0..<prefixEnd) { nfcSlicedSelf in
return _binaryCompare(nfcSlicedSelf, nfcPrefix) == 0
}
}
}
return starts(with: prefix)
}
}
这意味着(如果我理解正确的话):如果字符串和候选前缀都使用基于 UTF-8 的存储,那么将直接比较 UTF-8 字节。否则它会退回到 starts(with:)
并进行基于 Character
的比较。
所以结果没有区别,但是 hasPrefix()
针对原生 Swift 字符串进行了优化。
注意:这是来自master(Swift5)的分支,早期版本情况可能有所不同。