Swift提供了一种高性能的,兼容Unicode编码的String实现作为标准库的一部分。在 Swift2中,String类型不再遵守CollectionType协议。在以前,String类型是字符的一个集合,类似于数组。现 在,String类型通过一个characters属性来提供一个字符的集合。

AD:

Swift提供了一种高性能的,兼容Unicode编码的String实现作为标准库的一部分。在Swift2中,String类型不再遵守 CollectionType协议。在以前,String类型是字符的一个集合,类似于数组。现在,String类型通过一个characters属性来 提供一个字符的集合。

为什么会有这样的变化呢?虽然模拟一个字符串作为字符的集合看起来非常自然,但是String类型与真正的集合类如Array、Set以及 Dictionnary等类型表现得完全不同。这是一直都存在的,但是由于Swift2中增加了协议扩展,这些不同就使得很有必要做些基本改变。

不同于部分的总和

当你在集合中添加一个元素时,你希望集合中包含那个元素。也就是说,当你给一个数组增加一个值,这个数组就包含了那个值。这同样适用于 Dictionary和Set。无论如何,当你给字符串拼接一个组合标记字符(combing mark character)时,字符串本身的内容就改变了。

比如字符串cafe,它包含了四个字符:c,a,f ,e:

  1. var letters: [Character] = ["c", "a", "f", "e"]
  2. var string: String = String(letters)
  3. print(letters.count) // 4
  4. print(string) // cafe
  5. print(string.characters.count) // 4

如果你在字符串后面拼接了组合重音符号U+0301  ? ,字符串仍然有四个字符,但是最后的字符现在是é:

  1. let acuteAccent: Character = "\u{0301}" // ′ COMBINING ACUTE ACCENT' (U+0301)
  2. string.append(acuteAccent)
  3. print(string.characters.count) // 4
  4. print(string.characters.last!) // é

字符串的characters属性不包含原始的小写字母 e,它也不包含刚刚拼接的重音符号?,字符串现在是一个带着重音符号的小写字母é:

  1. string.characters.contains("e") // false
  2. string.characters.contains("?") // false
  3. string.characters.contains("é") // true

如果你想要将字符串像其他集合类型那样看待,这种结果很令人惊讶,就像你在一个集合中添加了UIColor.redColor()和UIColor.greenColor(),但是集合会报告它自己包含了一个UIColor.yellowColor()

通过字符内容判断

字符串与集合之间另一个不同是它们处理“相等”的方式。

  • 只有在两个数组的元素个数相同,并且在每一个对应索引位置的元素也相等时两个数组才是相等的。

  • 只有在两个集合的元素个数相同,并且第一个集合中包含的元素,第二个集合也包括时两个集合才相等。

  • 两个字典只有在有相同的键值对时才相等。

然而,String类型的相等建立在标准相等的基础上。如果两个字符串有相同的语义和外观,即使它们实际上是用不同的Unicode码构成的,它们也是标准相等的。

考虑韩国的书写系统,包含了24个字母,或者叫Jamo,包含了单个的辅音和元音。当写出时这些字母就组成每个音节对应的字符。例如,字符 ([ga])是由字母 ([g])和[a]构成的。在Swift中,无论字符串是由分解的还是组合的字符构成的,都被认为是相等的。

这种行为再一次与Swift中的集合类型区别开来。这很令人惊讶就像是数组中的值 被认为和相等。

取决于你的视角

字符串不是集合。但是它们确实也提供了许多遵守CollectionType协议的views:

characters是Character类型值的集合,或者扩展字形群集(extended grapheme clusters

unicodeScalars是Unicode量值的集合(Unicode scalar values

utf8是UTF-8编码单元的集合(UTF-8

utf16是UTF-16编码单元的集合(UTF-16

让我们来看之前单词 “café”的例子,由几个单独的字符[ c, a, f, e ] 和 [ ? ]构成,下面是多种字符串的Views中所包含的内容:

characters属性将文字分段为扩展字形群集,差不多接近用户看到的字符(在这个例子中指c, a, f, 和 é)。由于字符串必须对整个字符串中的每一个位置(称为码位(code point))进行迭代以确定字符的边界,因此取得这个属性的时间复杂度是线性的 O(n)。当处理包含了人类可读文本的字符串,以及上层的本地敏感的Unicode计算程序时,例如用到的 localizedStandardCompare(_:)方法和localizedLowercaseString 属性,都需要将字符逐字进行处理。

unicodeScalars属性提供了存储在字符串中的量值,如果原始的字符串是通过字符é而不是e + ?创建的,这就会通过unicodeScalar属性表示出来。当你对数据进行底层操作的时候使用这个API。

utf8和utf16属性对应地提供了它们所代表的代码点(code points),这些值与字符串被转化时写入一个文件中的实际字节数是相一致的,并且来自一种特定的编码方式。

UTF-8 编码单元(code units)被许多 POSIX 的字符串处理 API 所使用,而 UTF-16 编码单元(code units)则始终被用于表示 Cocoa 和 Cocoa Touch中的字符串长度和偏移量。

如果想了解更多 Swift 中关于字符和字符串的信息,请看The Swift Programming Language和 The Swift Standard Library Reference.

读懂Swift 2.0中字符串设计思路的改变的更多相关文章

  1. 《从零开始学Swift》学习笔记(Day 7)——Swift 2.0中的print函数几种重载形式

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift 2.0中的print函数有4种重载形式: l   print(_:).输出变量或常量到控制台,并且换行. l   print(_:_:).输出 ...

  2. [kx]为什么计算机能读懂 1 和 0 ?

    CPU如何实现运算的? 下面是一个小伙的总结, 从物理电路到逻辑运算到数字电路,一步一步的好理解. 最好能看看那本<编码 隐匿在计算机软硬件背后的语言>的书. 为什么计算机能读懂 1 和 ...

  3. iOS -Swift 3.0 -String(字符串常规用法)

    // // ViewController.swift // Swift-String // // Created by luorende on 16/9/10. // Copyright © 2016 ...

  4. 如何读懂Oracle文档中的语法图(转)

    本文转载自:http://kyle.xlau.org/posts/syntax-diagrams.html Oracle文档中用到了两种表达语法的方法,语法图和BNF. BNF, Backus-Nau ...

  5. 【转】如何读懂Oracle文档中的语法图

    转自:http://blog.itpub.net/22990797/viewspace-750157/ Oracle文档中用到了两种表达语法的方法,语法图和BNF. BNF, Backus-Naur ...

  6. Swift 4.0 中的错误处理及抛出错误

    在Swift的标准库,很多方法名后都带有'throws'这个关键词, 'throws'表示该方法在执行过程中遇到错误则抛出,但不会crash. 下面是Swift标准库中的一个构造方法,String.D ...

  7. 浅谈zygote服务中的设计思路

    zygote服务是Android启动和服务APK的核心服务,每个APK都是通过zygote启动,今日阅读它的源码学习到一个不错的设计思路. 首先看看一个APK通过zygote的启动流程: 按照一般的设 ...

  8. swift 2.0 语法 字符串

    //: Playground - noun: a place where people can play import UIKit /*: 字符串 * OC中的字符串是一个对象, Swift中的字符串 ...

  9. 一文读懂什么是Java中的自动拆装箱

    基本数据类型 基本类型,或者叫做内置类型,是Java中不同于类(Class)的特殊类型.它们是我们编程中使用最频繁的类型. Java是一种强类型语言,第一次申明变量必须说明数据类型,第一次变量赋值称为 ...

随机推荐

  1. 注册表:无法打开 XXX 由于某个错误无法打开该密钥。详细信息:拒绝访问

    错误原因:没有注册表用户权限. 正确添加用户权限的步骤如下:(跟着图片步骤) 右击该项,权限: 选中想要添加为当前所有者的用户后,点击应用.如果没用户显示,可以从“其他用户或组”中添加进来. 权限添加 ...

  2. hud 2089 不要62 (数位dp)

    #include<stdio.h> #include<string.h> #include<math.h> #define max 10 ]; int number ...

  3. C#复习一( Twenty Days)

      今天开始将要复习最近所学的一些C#知识.下面就来总结一下今天所复习的内容,以此来巩固我对C#知识的掌握.今天主要以举几个程序为例. 首先还是要注意代码的规范: –注释//,/**/,/// –骆驼 ...

  4. sp_makewebtask

      Transact-SQL 参考 sp_makewebtask 创建一项生成 HTML 文档的任务,该文档包含执行过的查询返回的数据. 说明  所有 Web 作业在企业管理器的"作业分类& ...

  5. CentOS下成功挂载xxxxxDVDx.iso并使用yum安装软件

    CentOS下成功挂载xxxxxDVDx.iso并使用yum安装软件 **不断尝试,终能到达彼岸** 测试环境为Win7 32位,VirtualBOx4.2.16+CentOS6.5,可分别到virt ...

  6. linux:如何修改用户的密码

    1.首先,要用CRT软件连接Linux系统. 2.首选,确认是用root用户登录系统的. 输入命令: id ,查看登录用户信息. 3.若修改root自己的密码,直接输入 passwd . 输入两遍,新 ...

  7. bzoj 1046 : [HAOI2007]上升序列 dp

    题目链接 1046: [HAOI2007]上升序列 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3620  Solved: 1236[Submit] ...

  8. A Byte of Python 笔记(10)输入/输出:文件和储存器

    第12章  输入/输出 大多数情况下,我们需要程序与用户交互.从用户得到输入,然后打印一些结果. 可以分别使用 raw_input 和 print 语句来完成这些功能.对于输出,可以使用多种多样的 s ...

  9. Python 城市菜单详解(超详解)

      print("--------城市查询系统---------") print("--------按数值进行查询--------") menu={" ...

  10. [LeetCode]题解(python):124-Binary Tree Maximum Path Sum

    题目来源: https://leetcode.com/problems/binary-tree-maximum-path-sum/ 题意分析: 给定一棵树,找出一个数值最大的路径,起点可以是任意节点或 ...