加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Friday Q&A 2015-11-06:为什么 Swift 中的 String API 如此

发布时间:2020-12-14 02:37:34 所属栏目:百科 来源:网络整理
导读:作者:Mike Ash,原文链接,原文日期:2015-11-06 译者:Cee;校对:numbbbbb;定稿:numbbbbb 译者注:可以结合 WWDC 2015 Session 227 - What's New in Internationalization 一起学习 欢迎来到本期因修改了很多次稿而推迟发布的周五问答。我发现很多人在

作者: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é∞                        

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读