美文网首页
1.6.Swift 3忘记旧有的"C风格"字符串吧

1.6.Swift 3忘记旧有的"C风格"字符串吧

作者: CDLOG | 来源:发表于2018-12-25 14:21 被阅读0次

Variable length unicode

于是,现如今的unicode采用的是可变长度编码方案。而所谓的“可变长度”包含了两个意思:

  • “编码单位(code unit)”的长度是可变的;
  • 构成同一个字符的“编码单位”组合也是可变的;

什么是code unit呢?简单来说,code unit和ASCII码的形式是非常类似的,它们是一个个具体的数值。不同的是,它可以由多种长度单位的数字构成:

第一种是用多个连续的8-bit数字表示一个unicode,这就是我们熟知的UTF-8编码。这种编码方式可以很好的对ASCII编码实现兼容。例如,人民币符号¥的UTF-8编码是:C2 A5

第二种是用一个16-bit数字表示一个unicode,这种编码方式叫做UTF-16。例如,¥的UTF-16编码是:00A5

最后,当然就是UTF-32编码,¥的UTF-32编码是:000000A5,你应该不难理解它的含义;

Unicode scalar?

当然,无论我们用什么编码来表示字符,和ASCII编码一样,每一个可变长unicode字符最终也会对应一个数字来表示它的编码值,这个值叫做code point。现如今,这个值的的范围是[0, 0x10FFFF],而我们只用了还不到12%的空间。因此,还有大量的空间允许我们添加诸如emoji这样的符号。

理解Surrogate pair

看到这里,你可能会想,如果我们使用UTF-16编码,根本无法全部表示上面定义的code point啊。为了解决这个问题,unicode标准保留了UTF-16编码空间中的一些值,它们永远不会被定义成字符,而是和其它UTF-16的编码值组合在一起,表示一个unicode字符。

来看一个例子:

💖 Sparkling heart的code point是1F496,显然,他不能用一个UTF-16来表示,因此,整个编码过程是这样的:

  1. 用code point减去0x10000,得到0x0F496;
  2. 把这个数字变成二进制0000 1111 0100 1001 0110;
  3. 取10-MSB:0000 1111 01和10-LSB:00 1001 0110;
  4. 用0xD800 + 10-MSB得到0xD83D;
  5. 用0xDC00 + 10-LSB得到0xDC96;
  6. 这样 D83D DC96 就是这个unicode的UTF-16编码;

而我们用到的0xD800和0xDC00,就叫做surrogate pair。

什么是unicode scalar?

理解了surrogate pair之后,就不难理解unicode scalar了。简单来说,它就是除了surrogate pair之外的code unit。在后面的视频中,我们可以看到,Swift中,我们可以使用\u{1F496}这样的方式,来表示一个unicode scalar。

忘了String是字符数组这个事情吧

很长时间以来,在其他编程语言里,为了降低复杂性,人们总是试图隐藏一个事实:

"一个在屏幕上显示的字符可能由多个code unit组合而成。"

但这却给开发者理解unicode,甚至在处理unicode的代码上留下了很多难以发现和处理的bug。于是,在Swift里,String并没有这样做,开发团队对这个类型最重要的一个设计目标就是尽可能保持这个类型在Unicode上的语义正确。

当然,这样做也是有代价的。在Swift里,String已经彻底不再是一个集合类型。而是一个提供了从多个维度展现一个Unicode视图的类型。你可以得到它的多个Characters,可以看到它的UTF-8 / UTF-16 / Unicode scalar值等等。

所以,彻底忘了String是一个字符数组这样的事情吧。哪怕是从概念上,也不要这样去理解Swift中的String。让自己用一个全新的方式,去理解现如今我们需要处理的字符。

相关文章

  • 1.6.Swift 3忘记旧有的"C风格"字符串吧

    Variable length unicode 于是,现如今的unicode采用的是可变长度编码方案。而所谓的“可...

  • C++<第十九篇>:字符串

    C++ 中的字符串有两种形式:(1)C风格的字符串 (2)C++引入的 string 类型的字符串。 (1)C风格...

  • 22 STL(二)容器string

    string我们之前使用过,如给类的属性定为字符串就要include ,是C++风格的字符串,c风格的字符串是个c...

  • C++ 字符串

    C++ 提供了以下两种类型的字符串表示形式: C 风格字符串 C++ 引入的 string 类类型 1、C 风格字...

  • C++11新特性(20)-用string对象处理文件名

    C风格字符串 从C语言开始,就已经实现了对字符串的支持。为了处理C风格字符串,C语言标准库提供了一组函数,它们被定...

  • c++ string怎样判断字符串里面是否含有某个字符串?

    有两种方法可以使用,C++风格,或C风格。一、C++风格。C++的string类提供了字符串中查找另一个字符串的函...

  • 字符串

    C++提供了两种字符串的表示形式: C风格字符 C++引入的string类型 C风格 函数 C++中的String类

  • 字符串

    字符串 C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持。字符串实际上是使用 null 字符 '\0...

  • Swift 3 初上手编程——忘记旧有的"C风格&qu

    配套高清视频 如果你是个从C语言那个年代一路走来的程序员,无论你在用什么语言编程,String就是个长度固定的字符...

  • Python格式化字符串打印

    格式化打印 可以对字符串格式化处理的手段:字符串方法类C风格的%打印输出方法Python特有的format函数 F...

网友评论

      本文标题:1.6.Swift 3忘记旧有的"C风格"字符串吧

      本文链接:https://www.haomeiwen.com/subject/hcxlkqtx.html