Swift 提供了一種高性能的、兼容 Unicode 的字符串實現,這也成為了它自身標準庫的一部分。在 Swift 2 中, String 類型不再遵守 CollectionType 協議,那時 String 是 字符 類型的集合,就像是數組。現在 String 提供了一種公開字符集合視圖的字符屬性。 為什麼要這麼改變?字符串作為字符的集合, String 類型的行為和數組、集合以及字典有著相當大的不同,儘管這看起來是很合乎常理的模型。事實上也一直是這樣,但是由於 Swift 2 添加的一些協議上的擴展導致了其根本上的一些必要的改變。
不同於其部分的總和
當添加一個元素到合集當中時,我們期望這個合集能夠容納這個元素。就好像你給數組末尾添加一個值,數組就容納了這個值。集合與字典也是這個樣子。總之,當你給給字符串末尾添加一個組合符號的時候,字符串中的內容會自動改變。 假設我們設定一個字符串 “ 咖啡店 “,也就是四個字符 C , 一個 , F , Ë :
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 |
如果你在字符串末尾添加一個聲調字符 “ 該+0301 ” 也就是符號 “ “ ” 字符串仍然擁有四個字符,但是最後一個字符卻變成了“這是 “
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!) // é |
字符串的字符屬性不再包含原來的小寫字母 “ Ë “ ,也不包含我們添加的聲調符號 “ “ “。字符串現在包含了一個帶著聲調符號““”的小寫字母 “ 這是 “ :
1 2 3 |
string.characters.contains("e") // false string.characters.contains("´") // false string.characters.contains("é") // true |
如果我們把其他合集都像字符串這樣對待,那麼比如說把 的UIColor.Redcoat() 和 的UIColor.綠彩() 添加到一個集合裡然後集合就有了 的UIColor.黃色顏色() 將不足為奇。
基於內容字符的判斷
另一個字符串和合集不同的地方是他們如何定義相等。
- 兩個數組只有同時擁有相同的長度,並且每對相應索引處的元素相等時候才會相等。
- 兩個集合只有同時擁有相同的長度,並且每一個元素都被兩者包含時候才會相等。
- 兩個字典只有他們擁有相同的鍵值集合才會相等。
總之, String 是基於規範化相等來定義相等的。字符如果具有相同的語言意義和外形,我們就說它們規範化相等,就算是他們後台是由不同的 Unicode 組成也是一樣。 比如說韓國的文字系統由24個符號或聲調組成,代表單獨的輔音和元音。只有把它們寫出來的時候才會組成可讀的字符。 舉個栗子來講,符號“a”的([GA])由字符 “ᄀ” ([g]) 和 “ᅡ” [一個]組成。在 Swift 語言當中,字符串的相等不再考慮它們是由分解還是複合字符序列:
1 2 3 4 |
let decomposed = "\u{1100}\u{1161}" // ᄀ + ᅡ let precomposed = "\u{AC00}" // 가 decomposed == precomposed // true |
再說一句,這個行為與 Swift 中任何合集都有巨大的不同。一個有著 ? 和 ?的數組被視為與 ?相等將變得不足為奇。
取決於你的角度
字符串不是合集。但它確實還是提供 CollectionType 視圖的:
- 字符是字符值的合集,或者是擴展字形集群.
- unicode標量是 Unicode 標量值的合集.
- UTF8 是 UTF-8 代碼單位的合集.
- UTF16 是 UTF-16 代碼單位的合集.
如果我們把剛才那個栗子 “café”拿過來,由分解的複合字符序列組成 [ C, 一個, F, Ë ] 還有 [ “ ],這裡是各種類型字符串視圖,顯示了它們的組成:
- 字符屬性把用戶可感知字符文本(比如說c, 一個, F, 和 é)分割為擴展字形集群 。由於字符串必須遍歷整個字符串中的每個位置(每個位置被稱作代碼點)以確定字符邊界,訪問此屬性執行線性 0(N)時間。在處理那些包含人類可讀文本字符串時,比如說那些 localizedStandardCompare(_:) 方法 和 本地化小寫字符串 屬性等 高級區分區域 Unicode 算法應當有線逐字符處理。
- Unicode標量 屬性公開的基礎標量值處存在字符串中。如果原始字符串使用預先組合的字符“ é”而不是分開的“ Ë + ´”,這將會反映在 Unicode 標量視圖當中。當你執行字符數據的低級操作時,請使用這個API。
- UTF8和UTF16分別為了支持UTF-8和UFT-16表示法並提供代碼點。這些值對應實際寫入文件時候的特定編碼。UTF-8代碼單位在很多POSIX字符串處理API中使用,而UTF-16則在Cocoa和Cocoa Touch框架中表示字符串長度和偏移量。
更多關於Swift 編程語言的字符串和字符內容,請閱讀 斯威夫特編程語言 以及 雨燕標準庫參考.
本文章內容翻譯自蘋果官方博客 在斯威夫特字符串 2 ,系本人學習為之,水準有限,如有不妥之處歡迎留言斧正。
本文由 落格博客 原創撰寫:落格博客 » Swift 2 中的 String 字符串
轉載請保留出處和原文鏈接:https://www.logcg.com/archives/1076.html