当把一个Unicode字符串写入文本文件或者以其他形式存储,字符串中的Unicode标量会被编码成Unicode定义的几种编码形式中的一种。每一种字符串编码形式都把字符串编码成更小块的编码单元。其中有:
UTF-8编码:把一个字符串以8位的一个编码单元进行编码
UTF-16编码:把一个字符串以16位的一个编码单元进行编码
UTF-32编码:把一个字符串以32位的一个编码单元进行编码
Swift提供了几种不同的方式去访问字符串的Unicode表示。我们可以使用for-in语句遍历字符串,然后去访问每一个字符的Unicode字形集。
当然,我们也可以使用洗面3中Unicode兼容的方式去访问字符串的值:
一个UTF-8编码单元的集合,通过属性 utf8 获取
一个UTF-16编码单元的集合,通过属性 utf16 获取
一个21位的Unicode标量值组成的集合,和UTF-32编码形式相等,通过属性 unicodeScalars获取
下面的每一个例子展示了下方字符串的不同的表示,一个由字符D,o,g,!!和🐶组成的字符串。
let dogString = "Dog‼🐶"
UTF-8表示
可以通过遍历属性uft8获得字符串的UTF-8的表示。这个属性是一个String.UTF8View类型的值,是一组8位无符号数字的集合。下图说明了每一个无符号数字和字符串UTF-8表示的对应关系:
for codeUnit in dogString.utf8 {
print("\(codeUnit) ", terminator: "")
}
// 打印 "68 111 103 226 128 188 240 159 144 182 ”
上面的例子中,开始三个数字编码单元(68, 111, 103)代表了字符D,o,g,这里的UTF-8表示和ASCII表示是一样的。接下来的三个数字编码单元(226, 128, 188)是一个3字节的UTF-8表示,代表了DOUBLE EXCLAMATION MARK(!!)字符。最后的4个编码单元(240, 159, 144, 182)是一个4字节UTF-8表示,代表了DOG FACE🐶字符。
UTF-16表示
可以通过遍历属性uft16获得字符串的UTF-16的表示。这个属性是一个String.UTF16View类型的值,是一组16位无符号数字的集合,下图说明了每一个无符号数字和字符串UTF-16表示的对应关系:
for codeUnit in dogString.utf16 {
print("\(codeUnit) ", terminator: "")
}
// 打印 "68 111 103 8252 55357 56374 ”
相同的,开始的三个编码单元(68, 111, 103) 代表了字符D,o,g,和UTF-8中的表示相同,都等于ASCII的表示。
第四个编码单元(8252)在数值上等于16进制的203C,表示了Unicode标量U+203C也就是字符DOUBLE EXCLAMATION MARK(!!),这个字符在UTF-16中可以用一个代码单元来表示。
第5个和第6个编码单元(55357,56374)是DOG FACE🐶在UTF-16中的代理对的表示。这里是一个高代理点U+D83D(55357)和一个低代理点U+DC36 (56374)。
Unicode标量表示
可以通过遍历属性unicodeScalars获得字符串的Unicode标量表示。这个属性是一个UnicodeScalarView类型的值,是一组unicode标量的集合。
每一个Unicode标量的value属性会返回一个21位的标量的值,表示了一个UInt32的值。
for scalar in dogString.unicodeScalars {
print("\(scalar.value) ", terminator: "")
}
// 打印 "68 111 103 8252 128054 ”
同样,开始三个Unicode标量(68, 111, 103)还是代表了字符D,o,g。
第4个编码单元(8252),还是和16进制的203C相等,表示了Unicode标量U+203C也就是字符DOUBLE EXCLAMATION MARK(!!)。
第5个编码单元(128054)在数值上等于16进制的1F436,表示了Unicode标量U+1F436,也就是字符DOG FACE(🐶)。
和获取Unicode编码单元的value属性不一样,每一个Unicode编码单元都可以被用来构造一个新的字符串,比如字符串插入:
for scalar in dogString.unicodeScalars {
print("\(scalar) ")
}
// D
// o
// g
// ‼
// 🐶
网友评论