当一个 Unicode 字符串被写进文本文件或者其他储存时,字符串中的 Unicode 标量会用 Unicode 定义的几种 编码格式(encoding forms)编码。每一个字符串中的小块编码都被称 代码单元(code units)。这些包括 UTF-8 编码格式(编码字符串为 8 位的代码单元), UTF-16 编码格式(编码字符串位 16 位的代码单元),以及 UTF-32 编码格式(编码字符串32位的代码单元)。
Swift 提供了几种不同的方式来访问字符串的 Unicode 表示形式。你可以利用 for-in
来对字符串进行遍历,从而以 Unicode 可扩展的字符群集的方式访问每一个 Character
值。该过程在 4.6. 使用字符 中进行了描述。
另外,能够以其他三种 Unicode 兼容的方式访问[字符串](/tag/59e.html)的值:
- UTF-8 代码单元集合(利用字符串的
utf8
属性进行访问) - UTF-16 代码单元集合(利用字符串的
utf16
属性进行访问) - 21 位的 Unicode 标量值集合,也就是字符串的 UTF-32 编码格式(利用字符串的
unicodeScalars
属性进行访问)
下面由 D
,o
,g
,‼
(DOUBLE EXCLAMATION MARK
, Unicode 标量 U+203C
)和 🐶
(DOG FACE
,Unicode 标量为 U+1F436
)组成的字符串中的每一个字符代表着一种不同的表示:let dogString = "Dog‼🐶"
UTF-8 表示
你可以通过遍历 String
的 utf8
属性来访问它的 UTF-8
表示。其为 String.UTF8View
类型的属性,UTF8View
是无符号 8 位(UInt8
)值的集合,每一个 UInt8
值都是一个字符的 UTF-8 表示:
Character | DU+0044 | oU+006F | gU+0067 | ‼U+203C | 🐶U+1F436 | |||||
---|---|---|---|---|---|---|---|---|---|---|
UTF-8 Code Unit | 68 | 111 | 103 | 226 | 128 | 188 | 240 | 159 | 144 | 182 |
Position | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
for codeUnit in dogString.utf8 {
print("\(codeUnit) ", terminator: "")
}
print("")
// 68 111 103 226 128 188 240 159 144 182
上面的例子中,前三个 10 进制 codeUnit
值(68
、111
、103
)代表了字符 D
、o
和 g
,它们的 UTF-8 表示与 ASCII 表示相同。接下来的三个 10 进制 codeUnit
值(226
、128
、188
)是 DOUBLE EXCLAMATION MARK
的3字节 UTF-8 表示。最后的四个 codeUnit
值(240
、159
、144
、182
)是 DOG FACE
的4字节 UTF-8 表示。
UTF-16 表示
你可以通过遍历 String
的 utf16
属性来访问它的 UTF-16
表示。其为 String.UTF16View
类型的属性,UTF16View
是无符号16位(UInt16
)值的集合,每一个 UInt16
都是一个字符的 UTF-16 表示:
Character | DU+0044 | oU+006F | gU+0067 | ‼U+203C | 🐶U+1F436 | |
---|---|---|---|---|---|---|
UTF-16 Code Unit | 68 | 111 | 103 | 8252 | 55357 | 56374 |
Position | 0 | 1 | 2 | 3 | 4 | 5 |
for codeUnit in dogString.utf16 {
print("\(codeUnit) ", terminator: "")
}
print("")
// 68 111 103 8252 55357 56374
同样,前三个 codeUnit
值(68
、111
、103
)代表了字符 D
、o
和 g
,它们的 UTF-16 代码单元和 UTF-8 完全相同(因为这些 Unicode 标量表示 ASCII 字符)。
第四个 codeUnit
值(8252
)是一个等于十六进制 203C
的的十进制值。这个代表了 DOUBLE EXCLAMATION MARK
字符的 Unicode 标量值 U+203C
。这个字符在 UTF-16 中可以用一个代码单元表示。
第五和第六个 codeUnit
值(55357
和 56374
)是 DOG FACE
字符的 UTF-16 表示。第一个值为 U+D83D
(十进制值为 55357
),第二个值为 U+DC36
(十进制值为 56374
)。
Unicode 标量表示
你可以通过遍历 String
值的 unicodeScalars
属性来访问它的 Unicode 标量表示。其为 UnicodeScalarView
类型的属性,UnicodeScalarView
是 UnicodeScalar
类型的值的集合。
每一个 UnicodeScalar
拥有一个 value
属性,可以返回对应的 21 位数值,用 UInt32
来表示:
Character | DU+0044 | oU+006F | gU+0067 | ‼U+203C | 🐶U+1F436 |
---|---|---|---|---|---|
Unicode Scalar Code Unit | 68 | 111 | 103 | 8252 | 128054 |
Position | 0 | 1 | 2 | 3 | 4 |
for scalar in dogString.unicodeScalars {
print("\(scalar.value) ", terminator: "")
}
print("")
// 68 111 103 8252 128054
前三个 UnicodeScalar
值(68
、111
、103
)的 value
属性仍然代表字符 D
、o
和 g
。
第四个 codeUnit
值(8252
)仍然是一个等于十六进制 203C
的十进制值。这个代表了 DOUBLE EXCLAMATION MARK
字符的 Unicode 标量 U+203C
。
第五个 UnicodeScalar
值的 value
属性,128054
,是一个十六进制 1F436
的十进制表示。其等同于 DOG FACE
的 Unicode 标量 U+1F436
。
作为查询它们的 value
属性的一种替代方法,每个 UnicodeScalar
值也可以用来构建一个新的 String
值,比如在字符串插值中使用:
for scalar in dogString.unicodeScalars {
print("\(scalar) ")
}
// D
// o
// g
// ‼
// 🐶