Swift: String starts(with:) vs hasPrefix

17

String.hasPrefix (或 [NSString hasPrefix])一直是Foundation的一部分。 但是,我刚刚注意到现在我们也有starts(with:)

这个方法来自于Sequence,但同样适用于String

我的问题是,我应该选择哪一个? 是否存在任何性能考虑因素? 我习惯了 Objective-C 时代的 hasPrefix,但 starts(with:) 更直观,并且适用于其他序列。

1个回答

25

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字符串进行了优化。
注意:这是来自主分支(Swift 5),在早期版本中情况可能不同。

有道理,我期望针对字符串的具体实现被优化。但是文档没有提及(String的starts(with:)的文档应该建议使用hasPrefix代替)。而且它实现在StringLegacy.swift中这一事实令人怀疑。 - noamtm
1
此外,如果String提供了一个经过优化的starts(with:)实现,那将更有意义。 - noamtm
@noamtm:String.start(with:)文档可能是从通用序列方法(String符合该方法)自动生成的。-我理解您对文件名的担忧,但我不知道它背后的意图。 - Martin R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接