我怎样才能得到一个字符的Unicode代码点?

我怎样才能提取一个给定的Character的Unicode代码点(S)没有先把它转换为一个String ? 我知道我可以使用以下内容:

 let ch: Character = "A" let s = String(ch).unicodeScalars s[s.startIndex].value // returns 65 

但似乎应该有一个更直接的方式来完成这个使用Swift的标准库。 “语言指南”部分中的“使用字符”和“Unicode”仅讨论迭代String中的String ,而不直接与Character s一起工作。

从我可以在文档中收集的内容,他们希望您从String获取Character值,因为它提供了上下文。 这个Character是用UTF8,UTF16还是21位代码点(标量)编码的?

如果你看看在Swift框架中如何定义一个Character ,它实际上是一个enum值。 这可能是由于来自String.utf8String.utf16String.unicodeScalars的各种表示。

看起来他们不希望你使用Character值而是Strings而你作为程序员决定如何从String本身获取这些值,从而允许保留编码。

也就是说,如果您需要以简洁的方式获取代码点,我会推荐一个像这样的扩展:

 extension Character { func unicodeScalarCodePoint() -> UInt32 { let characterString = String(self) let scalars = characterString.unicodeScalars return scalars[scalars.startIndex].value } } 

那么你可以这样使用它:

 let char : Character = "A" char.unicodeScalarCodePoint() 

总之,string和字符编码是一个棘手的事情,当你考虑到所有的可能性。 为了让每一个可能性代表,他们去了这个计划。

还记得这是一个1.0版本,我相信他们很快就会扩展Swift的语法糖。

我认为对Unicode有一些误解。 Unicode本身不是一种编码,它不会将任何字形集群(或“人物”从人类阅读的尊重)转换成任何types的二进制序列。 Unicode只是一个收集地球上所有语言(非官方还包括克林贡语)使用的所有字形集群的大桌子。 这些字形集群是由代码点(一个21位的数字在迅速,看起来像U + D800)组织和索引。 通过使用代码点,您可以在大Unicode表中find您要查找的字符

同时,称为UTF8,UTF16,UTF32的协议实际上是编码。 是的,有多种方法可以将Unicode字符编码为二进制序列。 使用哪种协议取决于您正在工作的项目,但大多数网页是由UTF-8编码的(您现在可以实际检查它)。

概念1: Unicode点被称为Swift中的Unicode标量

Unicode标量是从U + 0000到U + D7FF(含)或U + E000到U + 10FFFF(含)的任何Unicode代码点。 Unicode标量不包括Unicode代理对代码点,它是U + D800到U + DFFF(含)范围内的代码点。

概念2: 代码单元是编码的抽象表示。

考虑下面的代码片段

 let theCat = "Cat!🐱" for char in theCat.utf8 { print("\(char) ", terminator: "") //Code Unit of each grapheme cluster for the UFT8 encoding } print("") for char in theCat.utf8 { print("\(String(char, radix: 2)) ", terminator: "") //Encoding of each grapheme cluster for the UTF8 encoding } print("") for char in theCat.utf16 { print("\(char) ", terminator: "") //Code Unit of each grapheme cluster for the UFT-16 encoding } print("") for char in theCat.utf16 { print("\(String(char, radix: 2)) ", terminator: "") //Encoding of each grapheme cluster for the UTF-16 encoding } print("") for char in theCat.unicodeScalars { print("\(char.value) ", terminator: "") //Code Unit of each grapheme cluster for the UFT-32 encoding } print("") for char in theCat.unicodeScalars { print("\(String(char.value, radix: 2)) ", terminator: "") //Encoding of each grapheme cluster for the UTF-32 encoding } 

抽象表示的意思是 :代码单元是由base-10编码(十进制数)写的,它等于base-2编码(二进制序列)。 编码是为机器编写的,Code Unit更适合人类,读取比二进制序列容易。

概念3:一个字符可能有不同的Unicode点。 这取决于字符是如何被字形集群收缩的(这就是为什么我开始时的人类阅读方面“字符”

考虑下面的代码片段

 let precomposed: String = "\u{D55C}" let decomposed: String = "\u{1112}\u{1161}\u{11AB}" print(precomposed.characters.count) // print "1" print(decomposed.characters.count) // print "1" => Character != grapheme cluster print(precomposed) //print "한" print(decomposed) //print "한" 

precomposed decomposeddecomposed的字符在视觉上和语言上是相同的,但是如果它们使用相同的编码协议进行编码,则它们具有不同的Unicode点和不同的编码单元(参见下面的例子)

 for preCha in precomposed.utf16 { print("\(preCha) ", terminator: "") //print 55357 56374 128054 54620 } print("") for deCha in decomposed.utf16 { print("\(deCha) ", terminator: "") //print 4370 4449 4523 } 

额外的例子

 var word = "cafe" print("the number of characters in \(word) is \(word.characters.count)") word += "\u{301}" print("the number of characters in \(word) is \(word.characters.count)") 

摘要代码点 ,也就是Unicode中字符的位置索引,与UTF-8,UTF-16和UTF-32编码scheme无关。

进一步阅读

http://www.joelonsoftware.com/articles/Unicode.html

http://kunststube.net/encoding/

https://www.mikeash.com/pyblog/friday-qa-2015-11-06-why-is-swifts-string-api-so-hard.html

我同意你的看法,应该有一种直接从angular色获取代码的方法。 但是我能提供的只是一个简写:

 let ch: Character = "A" for code in String(ch).utf8 { println(code) } 

我认为问题是, Character不代表一个Unicode代码点。 它代表一个“Unicode字形集群”,它可以由多个代码点组成。

相反, UnicodeScalar表示一个Unicode代码点。

你有没有尝试过:

 import Foundation let characterString: String = "abc" var numbers: [Int] = Array<Int>() for character in characterString.utf8 { let stringSegment: String = "\(character)" let anInt: Int = stringSegment.toInt()! numbers.append(anInt) } numbers 

输出:

[97,98,99]

它也可能只是string中的一个字符。