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. Hibernate学习之缓存机制

    转自:http://www.cnblogs.com/xiaoluo501395377/p/3377604.html 一.N+1问题 首先我们来探讨一下N+1的问题,我们先通过一个例子来看一下,什么是N ...

  2. XCode里遇到 #include <XXX.h>file not found的解决方案

    最近在学习如何在C++里调用Java方法,遇到提示 #include <XXX.h> file  not  found 的问题.也google了好久都没有找到合适的解决方案. 认真的研究了 ...

  3. XHTML CSS 常见问题和解决方案

    原文地址:XHTML CSS 常见问题和解决方案 作为前端开发人员,在日常的页面制作时,不可避免的会碰上这样那样的问题,我挑选了其中的一些进行总结归档,希望对大家会有所帮助: 1.如何定义高度很小的容 ...

  4. python自学笔记(五)python文本操作

    一.python自带方法 r:read 读 w:write 写 a:append 尾行追加 先命令行进入python后 >>>d = open('a.txt','w') #在对应路径 ...

  5. 指针和引用区别 C++

    #include <iostream> using namespace std; int main(){ ; void cubeByPoint(int *);//指针传参声明 void c ...

  6. poj 1836 Alignment(线性dp)

    题目链接:http://poj.org/problem?id=1836 思路分析:假设数组为A[0, 1, …, n],求在数组中最少去掉几个数字,构成的新数组B[0, 1, …, m]满足条件B[0 ...

  7. Memcached源代码分析 - Memcached源代码分析之消息回应(3)

    文章列表: <Memcached源代码分析 - Memcached源代码分析之基于Libevent的网络模型(1)> <Memcached源代码分析 - Memcached源代码分析 ...

  8. linux 进程间信号量管理程序之sem_timedwait使用

    在开发过程中,有三个独立执行的程序模块,三个模块都对sqlite数据库进行读写操作.sqlite在linux共享性较差,所以须要增加相互排斥信号量解决三个模块訪问数据库该问题. 另外,在增加信号量后, ...

  9. Swift调用Objective C的FrameWork

    很多Github的库经过很多年的发展,源码都是OC写的,,所以,用Swift调用OC的库就是开发中难免遇到的的一个问题,本文以AFNetworking为例,讲解如何跨语言调用. 第一步 创建一个空的工 ...

  10. Android学习之Drawable(一)

    Drawable有很多种,它们表示一种图像概念,但它们不全是图片.Drawable是什么呢?下面是Google Android API中的定义: A Drawable is a general abs ...