String或NSString,应该是
作为一种现代编程语言, Swift在过去几年中迅速普及。 尽管在生产开发中大量采用Swift可以带来很多方面的优势,但有时仍不可避免地要与基于Objective-C的框架或库进行互操作。 例如, String
或NSString
,应该采用哪个或更适合我们当前的开发?
尽可能使用本机类型
通常,您应该尽可能使用Swift本机类型,因为它们经过优化可以编译以提高性能。 但是等等,我只是说不可避免 ,对吧? 让我们以基于Objective-C的类NSRegularExpression
为例。
let str = "Hello, playground" do { let expression = try NSRegularExpression(pattern: "\\s{1,}", options: [.anchorsMatchLines]) let range = NSRange(location: 0, length: str.characters.count) let matches = expression.matches(in: str, options: [], range: range) for match in matches { print(match) } } catch { print(error.localizedDescription) }
在上面的代码片段中,我们可以看到函数func matches(in string: String, options: NSRegularExpression.MatchingOptions = [], range: NSRange) -> [NSTextCheckingResult]
,仅接受NSRange
变量作为参数; 因此,将代码互操作并混合在一起使用String
, NSString
, Range
和NSRange
无疑是将Range
类型的str.startIndex..<str.endIndex
为NSRange
类的必要。 但是,经验丰富的Swift程序员可能会发现上述片段中也存在致命的缺陷。 它是关于计算字符串长度str.characters.count
。 由于Swift使用Extended Grapheme Clusters(扩展字素簇),这样的做法容易出错。 例如,Unicode笑脸符号。 Swift将其视为一个字符,但NSString
方法将其视为两个字符。
所以……有原则或建议吗?
如果我们不想在这种差异上花太多的精力,那么为了无风险,我的建议是,一旦NSRegularExpression
基于NSRegularExpression
-C的函数(如NSRegularExpression
, NSRegularExpression
为NSString
。 当然,在引入本机Swift功能之前,该策略将不是必需的。 我们可能有一天会看到RegularExpression
。
因此,为了修复上述缺陷。 计算长度的方法应类似于以下代码段。 总而言之,总是有本地方法来处理变量。 但是,无风险或不太容易出错的策略有时可以为我们节省一天的时间🙂
// Option 1: Cast String to NSString let range = NSRange(location: 0, length: (str as NSString).length) // Option 2: Calculate utf16 count when accessing on a Swift String value. let range = NSRange(location: 0, length: str.utf16.count)