苹果官方博客:Swift 2.0 中的字符串

更多优秀译文请关注我们的微信公众号:learnSwift

原文链接:Strings in Swift 2

Swift 在它的标准库中提供了高效、Unicode 兼容的字符串实现。在 Swift 2.0 中,字符串不再遵守 CollectionType 协议,而在此之前,字符串被视为是一系列 Characher 类型值的集合,行为与数组十分类似。现在,字符串提供了一个 characters 属性,可以获得这个字符串所包含的 Character 集合。

为何要有这样的改变呢?尽管把字符串当作一系列字符的集合是十分自然的想法,然而字符串的行为与普通的集合类型,比如 ArraySetDictionary 很不一样。虽然过去也存在差异,但是 Swift 2.0 推出了协议扩展,因此我们有必要针对这些差异做出一些根本性的改变。

与字序列的总合不同

向一个集合中添加元素时,我们期望这个集合将会包含这个元素。也就是说,向一个数组添加一个值时,这个数组将会包含这个值。这对集合(set)和字典也适用。但是,当我们向字符串添加一个组合标记字符(combing mark character)时,字符串的内容将会发生改变。

比如 cafe 这个字符串,它包含了 cafe 四个字符:

var letters: [Character] = ["c", "a", "f", "e"]
var string: String = String(letters)

print(letters.count) // 4
print(string) // cafe
print(string.characters.count) // 4

如果向字符串中添加一个组合重音字符 U+0301 ´,这个字符串还是包含四个字符,但是最后一个字符将会变为 é

let acuteAccent: Character = "\\u{0301}" // ´ COMBINING ACUTE ACCENT' (U+0301)

string.append(acuteAccent)
print(string.characters.count) // 4
print(string.characters.last!) // é

该字符串的 characters 属性将不包含原来的小写字母 e,也不会包含刚刚添加的重音符号 ´。 它会给小写字母 “e” 添加重音符号,使其变成 é

string.characters.contains("e") // false
string.characters.contains("´") // false
string.characters.contains("é") // true

如果我们将字符串与其它的集合类型等同视之,那么向集合(set)中添加 UIColor.redColor()UIColor.greenColor() 就可能会得到 UIColor.yellowColor() 这样的奇怪结果。

根据字符内容进行判断

字符串与其它集合类型的另一个差异就是如何判断两个值是否相等。

  • 两个数组只有在他们包含的元素个数完全一致并且每个位置上的元素都相等时,才被视为相等。
  • 两个集合(set)只有在他们包含的元素个数完全一致,并且每个包含在第一个集合中的元素也被第二个集合所包含时,才被视为相等。
  • 两个字典只有在他们包含相同的键值对时,才被视为相等。

然而,字符串是根据 规范等价(canonically equivalent) 来进行相等判断的。即使两个字符串的底层 Unicode 标量不一样,只要他们的语义跟表现形式是一致的,他们就被认为是相等的。

以韩语为例, 它们的手写形式包含了 24 个字母,或者称为 Jamo, 用以表达不同的元音和辅音。书写时,这些字母可以组合来代表音节。比如,“가” ([ga]) 这个字符是由字母 “ᄀ” ([g]) 和 “ᅡ” [a] 组合而成的。在 Swift 中判断字符串是否相等时,不会判断它们是否由其它字符组合而成,只会判断他们的语义与表达形式是否一致:

let decomposed = "\\u{1100}\\u{1161}" // ᄀ + ᅡ
let precomposed = "\\u{AC00}" // 가

decomposed == precomposed // true

这个行为与 Swift 中其它的集合类型差别很大。试想,如果向一个数组当中添加

两个元素,最后却得到一个
,想必写这段代码的程序员也会很惊讶吧。

取决于你的视角

字符串虽然不是集合类型。但是它提供了多个遵守 CollectionType 协议的属性,以提供不同的视角(views)

如果以前面示例中的单词 “café” 为例,将它分解成 [c, a, f, e] 和 [ ´ ] 的字符序列,下面以不同的视角来对这些字符序列进行表示:

café字符序列视角
café字符序列视角
  • characters 属性将文本分割为 扩展字形集群(extended grapheme clusters),即与用户所直接看到相一致的字符序列(在此处即为 c, a, f 和 é)。取得这个属性的时间复杂度是线性的 O(n), 因为字符串必须对整个字符串文本中的每一个位置(这里的位置被称为码位(code point))进行迭代以确定字符的边界。只要涉及到对人类可读(human-readable)文本,或者本地化(locale-sensitive)有关的 Unicode 算法时,比如 localizedStandardCompare(_:) 处理的字符串,或者 localizedLowercaseString 属性,都需要对字符串中的字符进行逐字的处理。
  • unicodeScalars 属性表示出了字符串底层所保存的标量值。如果原本的字符串是由预组合字符 é 而非分解的字符 e + ´ 所组成,则 é 会被以 Unicode标量的形式表示出来。当需要对字符串底层的字符数据进行处理的时候,我们可以使用这个 API。
  • utf8utf16 属性分别以 UTF-8 和 UTF-16 来对码位(code points)进行表示。这些数值与我们对一个特定的编码进行转换时,要真实写入文件的字节相对应。UTF-8 编码单元(code units)被许多 POSIX 的字符串处理 API 所使用,而 UTF-16 编码单元(code units)则被用于表示 Cocoa 和 Cocoa Touch中的字符串长度和偏移。

如果想了解更多 Swift 中关于的字符和字符串的信息,可以阅读The Swift Programming Languagethe Swift Standard Library Reference.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容