我开始学习Swift语言,我非常好奇Swift中的字符串和字符比较对语言环境不敏感是什么意思?这是否意味着所有字符都以UTF-8字符存储在Swift中?
Mar*_*n R 26
(现在为Swift 3更新了所有代码示例.)
比较Swift字符串与<基于所谓的"Unicode规范化形式D"(可用其计算
decomposedStringWithCanonicalMapping)进行字典比较
例如,分解
"ä" = U+00E4 = LATIN SMALL LETTER A WITH DIAERESIS
Run Code Online (Sandbox Code Playgroud)
是两个Unicode代码点的序列
U+0061,U+0308 = LATIN SMALL LETTER A + COMBINING DIAERESIS
Run Code Online (Sandbox Code Playgroud)
出于演示目的,我编写了一个小的String扩展,它将String的内容转储为Unicode代码点数组:
extension String {
var unicodeData : String {
return self.unicodeScalars.map {
String(format: "%04X", $0.value)
}.joined(separator: ",")
}
}
Run Code Online (Sandbox Code Playgroud)
现在让我们拿一些字符串,用它们排序<:
let someStrings = ["??", "ä?", "?x", "äx"].sorted()
print(someStrings)
// ["a", "ã", "?", "ä", "?", "b"]
Run Code Online (Sandbox Code Playgroud)
并在排序数组中转储每个字符串的Unicode代码点(原始和分解形式):
for str in someStrings {
print("\(str) \(str.unicodeData) \(str.decomposedStringWithCanonicalMapping.unicodeData)")
}
Run Code Online (Sandbox Code Playgroud)
输出
äx 00E4,0078 0061,0308,0078
?x 01DF,0078 0061,0308,0304,0078
?? 01DF,03C8 0061,0308,0304,03C8
ä? 00E4,03C8 0061,0308,03C8
Run Code Online (Sandbox Code Playgroud)
很好地表明,比较是通过分解形式的Unicode代码点的字典顺序完成的.
对于包含多个字符的字符串也是如此,如以下示例所示.同
let someStrings = ["??", "ä?", "?x", "äx"].sorted()
Run Code Online (Sandbox Code Playgroud)
上面循环的输出是
äx 00E4,0078 0061,0308,0078
?x 01DF,0078 0061,0308,0304,0078
?? 01DF,03C8 0061,0308,0304,03C8
ä? 00E4,03C8 0061,0308,03C8
Run Code Online (Sandbox Code Playgroud)
意思就是
"äx" < "?x", but "ä?" > "??"
Run Code Online (Sandbox Code Playgroud)
(这对我来说至少是意料之外的).
最后让我们将它与区域设置敏感的排序进行比较,例如瑞典语:
let locale = Locale(identifier: "sv") // svenska
var someStrings = ["?", "ä", "ã", "a", "?", "b"]
someStrings.sort {
$0.compare($1, locale: locale) == .orderedAscending
}
print(someStrings)
// ["a", "?", "ã", "b", "ä", "?"]
Run Code Online (Sandbox Code Playgroud)
如您所见,结果与Swift <排序不同.