作者:Mike Ash,原文链接,原文日期:2015-11-06
译者:Cee;校对:numbbbbb;定稿:numbbbbb
译者注:可以结合 WWDC 2015 Session 227 - What's New in Internationalization 一起学习
欢迎来到本期因修改了很多次稿而推迟发布的周五问答。我发现很多人在使用 Swift 时,都会抱怨 String
API 很难用。它很难学习并且设计得晦涩难懂,大多数人希望它能采用其他语言的字符串(String) API 设计风格。今天我就要来讲一下为什么 Swift 中的 String
API 会被设计成现在这样(最起码要解释清楚我的看法),以及为什么我最终会认为,就其基础设计而言 Swift 中的 String
API 是字符串 API 中设计得最好的。
<!-- more -->
什么是字符串?
在我们讨论这点之前,首先需要建立一个基本的概念。我们总是把字符串想得很肤浅,很少有人能够深入思考它的本质。深思熟虑才能有助于我们理解接下来的内容。
从概念上来说,什么是字符串呢?从表面上看,字符串就是一段文本。"Hello,World"
是字符串;"/Users/mikeash"
和 "Robert'); DROP TABLE Students;--"
也是字符串。
(顺道讲一下,我认为不应该把这些不同的文本表述概念看作是同样的字符串类型。人类可读的文本、文件路径、sql 查询语句,以及其他所有在概念上讲并不相同的东西,在语言表示层面上都应该被表示成不同的类型。我觉得这些概念上不同的字符串应当有不同的类型,这也能大幅减少 bug 数量。尽管我并没有发现有哪个语言或者标准库做到了这点。)
那么在底层,这些常见的「文本」概念又是怎么被表示的呢?唔,得看情况。有很多不同的解决方法。
在很多语言中,字符串是用于存放字节(bytes)的数组(array)。程序所要做的就是为这些字节赋值。这种字符串的表示方法在 C++ 中是 std::string
类型,Python 2、Go 和其他语言也是这样。
C 语言对于字符串的表示就比较古怪和特殊。在 C 语言中,字符串是指向一串非零字节序列(sequence of non-zero bytes)的指针,以零字节位表示字符串的结束。基本的使其实和数组一样,但是 C 语言中的字符串不能包含零字节位,并且诸如查询字符串长度这样的操作需要扫描内存。
很多新语言把字符串定义成了一串 UCS-2 或者 UTF-16 码元(code unit)的集合。Java、C# 还有 JavaScript 是其中的代表。同样,在 Objective-C 中也使用了 Cocoa 和 Nsstring
。这可能是一个历史遗留问题。Unicode 在 1991 年被提出时(译者注:1991 年 10 月发布 Unicode 1.0.0),当时的系统都是 16 位。很多流行的编程语言在那个时代被设计出来,并且将 Unicode 作为字符串的构成基础。在 1996 年,Unicode 在 16 位系统上经历了爆发性的增长(译者注:1996 年 7 月发布了 Unicode 2.0,字库从 7161 个字元变成了 38950 个),这些语言再要改变字符串的编码方式已为时已晚。这时,由于 UTF-16 的编码方式能够将更大的数字编码为一组 16 位码元的集合,因此将字符串视为 16 位码元序列的基本想法就这样延续了下来。
这种想法的一个变体就是将字符串定义成 UTF-8 码元序列,其中组成的码元是 8 位的。总体上来说和 UTF-16 的表示方法很接近,但是对于 ASCII 字符串来说,能够有更加紧凑的表示空间,而且避免了在传递字符串进入函数时,由于这些函数只接受 C 语言风格类型(也就是 UTF-8 字符串)而导致的转换。
也有些语言将字符串表示为 Unicode 码位(code point)指向的一段字符序列。Python 3 中就是这么实现的,在很多 C 语言实现中也提供了内置的 wchar_t
类型。
简短概括一下,一个字符串通常情况下会被当做某些特定字符(character)的序列,其中字符通常是一个字节,或者是一个 UTF-16 码元,又或者是一个 Unicode 码位。
问题
将字符串表示成一段连续「字符」的序列的确很方便。你可以把字符串看作是数组(array)(通常情况下就是个数组),这样就很容易获得字符串的子串、从字符串头部或者尾部取出部分元素、删除字符串的某部分、获取字符总数,等等。
问题是我们身边遍布着 Unicode,而 Unicode 会让事情变得很复杂。简单看一个字符串的例子,看一下它是怎么工作的:
aé∞版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。