当前位置: 首页 > 科技观察

了解Swift2.0中字符串设计思想的变化

时间:2023-03-16 16:10:35 科技观察

Swift提供了一个高性能、兼容Unicode的字符串实现作为标准库的一部分。在Swift2中,String类型不再符合CollectionType协议。以前String类型是字符的集合,类似于数组。现在,String类型通过字符属性提供字符集合。为什么会有这样的变化?尽管将字符串模拟为字符集合看起来很自然,但String类型的行为与Array、Set和Dictionary等真正的集合类完全不同。这一直存在,但随着Swift2中协议扩展的添加,这些差异需要进行一些根本性的改变。与将元素添加到集合时的部分总和不同,您希望集合包含该元素。也就是说,当您向数组添加一个值时,该数组包含该值。这同样适用于Dictionary和Set。但是,当您将组合标记字符连接到字符串时,字符串本身的内容会发生变化。例如,字符串cafe包含四个字符:c、a、f、e:varletters:[Character]=["c","a","f","e"]varstring:String=String(letters)print(letters.count)//4print(string)//cafeprint(string.characters.count)//4如果拼接组合重音符号U+0301?在字符串之后,字符串仍然有四个字符,但是***字符现在是é:letacuteAccent:Character="\u{0301}"//'COMBININGACUTEACCENT'(U+0301)string.append(acuteAccent)print(string.characters.count)//4print(string.characters.last!)//é字符串的characters属性不包含原来的小写字母e,也不包含刚刚拼接的重音字符?,字符串现在带重音字符的小写字母é:string.characters.contains("e")//falsestring.characters.contains("?")//falsestring.characters.contains("é")//true如果你想像对待其他集合类型一样对待字符串,这样的结果是令人惊讶的,就像你在一个集合中添加了UIColor.redColor()和UIColor.greenColor(),但是集合会报告它包含一个UIColor.yellowColor()来判断差异string和collectionbycharactercontent之间的另一个区别是它们处理“相等性”的方式。只有当两个数组具有相同数量的元素并且每个对应索引位置的元素都相等时,这两个数组才相等。只有当两个集合具有相同数量的元素并且第一个集合中包含的元素也包含在第二个集合中时,这两个集合才相等。两个字典只有在它们具有相同的键值对时才相等。但是,String类型的相等性基于标准相等性。如果两个字符串具有相同的语义和外观,则它们在规范上是相等的,即使它们实际上由不同的Unicode代码点组成。考虑由24个字母组成的韩语书写系统,或由单独的辅音和元音组成的Jamo。书写时,这些字母构成每个音节的相应字符。例如,字符([ga])由字母([g])和[a]组成。在Swift中,字符串被认为是相等的,无论它们是由分解字符还是组合字符组成。这种行为再次将它与Swift中的集合类型区分开来。令人惊讶的是,数组中的值之和如何被认为是相等的。根据您的观点,字符串不是集合。但它们确实提供了一些符合CollectionType协议的视图:characters是Character类型值的集合,或者说扩展字形簇(extendedgraphemeclusters)unicodeScalars是Unicode标量值(Unicodescalarvalues)的集合utf8是一个UTF-8编码单元集合(UTF-8)utf16是UTF-16编码单元(UTF-16)的集合让我们看前面的单词“café”的例子,由几个单独的字符组成[c,a,f,e]和[?]形式,以下是各种字符串的Views中包含的内容:characters属性将文本分割成扩展的字形簇,近似于用户看到的字符(本例中的c、a、f和é)。由于字符串必须遍历整个字符串中的每个位置(称为代码点)以确定字符边界,因此获取该属性的时间复杂度为线性O(n)。在处理包含人类可读文本的字符串时,以及上层对语言环境敏感的Unicode计算过程,例如使用的localizedStandardCompare(_:)方法和localizedLowercaseString属性,需要对字符进行字面处理。unicodeScalars属性提供存储在字符串中的值。如果原始字符串是从字符é而不是e+?创建的,这将由unicodeScalar属性指示。在对数据执行低级操作时使用此API。utf8和utf16属性提供了它们所代表的代码点,这些代码点对应于字符串转换时写入文件的实际字节数,并且来自特定的编码。许多POSIX字符串处理API使用UTF-8代码单元,而UTF-16代码单元始终用于表示Cocoa和CocoaTouch中的字符串长度和偏移量。有关Swift中字符和字符串的更多信息,请参阅TheSwiftProgrammingLanguage和TheSwiftStandardLibraryReference。