讀懂Swift 2.0中字符串設計思路的改變

Swift提供了一種高性能的,兼容Unicode編碼的String實現做爲標準庫 的一部分。在Swift2中,String類型再也不遵照CollectionType協議。在之前,String類型是字符的一個集合,相似於數組。現 在,String類型經過一個characters屬性來提供一個字符的集合。html

爲 什麼會有這樣的變化呢?雖然模擬一個字符串做爲字符的集合看起來很是天然,可是String類型與真正的集合類如Array、Set以及 Dictionnary等類型表現得徹底不一樣。這是一直都存在的,可是因爲Swift2中增長了協議擴展,這些不一樣就使得頗有必要作些基本改變。數組

不一樣於部分的總和app

當 你在集合中添加一個元素時,你但願集合中包含那個元素。也就是說,當你給一個數組增長一個值,這個數組就包含了那個值。這一樣適用於Dictionary 和Set。不管如何,當你給字符串拼接一個組合標記字符(combing mark character)時,字符串自己的內容就改變了。性能

好比字符串cafe,它包含了四個字符:c,a,f ,e:編碼

1
2
3
4
5
6
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  ? ,字符串仍然有四個字符,可是最後的字符如今是é:
spa

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

字符串的characters屬性不包含原始的小寫字母 e,它也不包含剛剛拼接的重音符號?,字符串如今是一個帶着重音符號的小寫字母é:
scala

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

若是你想要將字符串像其餘集合類型那樣看待,這種結果很使人驚訝,就像你在一個集合中添加了UIColor.redColor()和UIColor.greenColor(),可是集合會報告它本身包含了一個UIColor.yellowColor()code

經過字符內容判斷orm

字符串與集合之間另外一個不一樣是它們處理「相等」的方式。htm

  • 只有在兩個數組的元素個數相同,而且在每個對應索引位置的元素也相等時兩個數組纔是相等的。

  • 只有在兩個集合的元素個數相同,而且第一個集合中包含的元素,第二個集合也包括時兩個集合才相等。

  • 兩個字典只有在有相同的鍵值對時才相等。

然而,String類型的相等創建在標準相等的基礎上。若是兩個字符串有相同的語義和外觀,即便它們其實是用不一樣的Unicode碼構成的,它們也是標準相等的。

考慮韓國的書寫系統,包含了24個字母,或者叫Jamo,包含了單個的輔音和元音。當寫出時這些字母就組成每一個音節對應的字符。例如,字符13.jpg13.jpg ([ga])是由字母14.jpg ([g])和15.jpg[a]構成的。在Swift中,不管字符串是由分解的仍是組合的字符構成的,都被認爲是相等的。
16.jpg

這種行爲再一次與Swift中的集合類型區別開來。這很使人驚訝就像是數組中的值 images.pngsalmon-149372_640.png被認爲和234728-13121619123590.jpg相等。

取決於你的視角

字符串不是集合。可是它們確實也提供了許多遵照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中所包含的內容:

QQ截圖20150824161609.jpg

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中的字符串長度和偏移量。

 

本文源自轉載

相關文章
相關標籤/搜索