標籤:des http io os 使用 ar for 檔案 art
字串和字元(Strings and Characters)
本頁包含內容:
- 字串字面量
- 初始化Null 字元串
- 字串可變性
- 字串是實值型別
- 使用字元
- 計算字元數量
- 連接字串和字元
- 字串插值
- 比較字串
- 字串大小寫
- Unicode
String是例如“hello, world”,“海賊王” 這樣的有序的Character(字元)類型的值的集合,通過String類型來表示。
Swift 的String和Character類型提供了一個快速的,相容 Unicode 的方式來處理代碼中的文本資訊。 建立和操作字串的文法與 C 語言中字串操作相似,輕量並且易讀。 字串串連操作只需要簡單地通過+號將兩個字串相連即可。 與 Swift 中其他值一樣,能否更改字串的值,取決於其被定義為常量還是變數。
儘管文法簡易,但String類型是一種快速、現代化的字串實現。 每一個字串都是由獨立編碼的 Unicode 字元組成,並提供了以不同 Unicode 表示(representations)來訪問這些字元的支援。
Swift 可以在常量、變數、字面量和運算式中進行字串插值操作,可以輕鬆建立用於展示、儲存和列印的自訂字串。
注意:
Swift 的String類型與 Foundation NSString類進行了無縫橋接。如果您利用 Cocoa 或 Cocoa Touch 中的 Foundation 架構進行工作。所有NSString API 都可以調用您建立的任意String類型的值。除此之外,還可以使用本章介紹的String特性。您也可以在任意要求傳入NSString執行個體作為參數的 API 中使用String類型的值作為替代。 更多關於在 Foundation 和 Cocoa 中使用String的資訊請查看 Using Swift with Cocoa and Objective-C。
字串字面量(String Literals)
您可以在您的代碼中包含一段預定義的字串值作為字串字面量。 字串字面量是由雙引號 ("") 包裹著的具有固定順序的文本字元集。
字串字面量可以用於為常量和變數提供初始值。
let someString = "Some string literal value"
注意:
someString常量通過字串字面量進行初始化,Swift 因此推斷該常量為String類型。
字串字面量可以包含以下特殊字元:
- 逸出字元
\0(Null 字元)、\\(反斜線)、\t(水平定位字元)、\n(分行符號)、\r(斷行符號符)、\"(雙引號)、\‘(單引號)。
- 單位元組 Unicode 標量,寫成
\xnn,其中nn為兩位十六進位數。
- 雙位元組 Unicode 標量,寫成
\unnnn,其中nnnn為四位十六進位數。
- 四位元組 Unicode 標量,寫成
\Unnnnnnnn,其中nnnnnnnn為八位十六進位數。
下面的代碼為各種特殊字元的使用樣本。 wiseWords常量包含了兩個轉移特殊字元 (雙括弧);dollarSign、blackHeart和sparklingHeart常量示範了三種不同格式的 Unicode 標量:
let wiseWords = "\"我是要成為海賊王的男人\" - 路飛"// "我是要成為海賊王的男人" - 路飛let dollarSign = "\x24" // $, Unicode 標量 U+0024let blackHeart = "\u2665" // ♥, Unicode 標量 U+2665let sparklingHeart = "\U0001F496" // ??, Unicode 標量 U+1F496
初始化Null 字元串 (Initializing an Empty String)
為了構造一個很長的字串,可以建立一個Null 字元串作為初始值。 可以將空的字串字面量賦值給變數,也可以初始化一個新的String執行個體:
var emptyString = "" // Null 字元串字面量var anotherEmptyString = String() // 初始化 String 執行個體// 兩個字串均為空白並等價。
您可以通過檢查其Boolean類型的isEmpty屬性來判斷該字串是否為空白:
if emptyString.isEmpty { println("什麼都沒有")}// 列印輸出:"什麼都沒有"
字串可變性 (String Mutability)
您可以通過將一個特定字串分配給一個變數來對其進行修改,或者分配給一個常量來保證其不會被修改:
var variableString = "Horse"variableString += " and carriage"// variableString 現在為 "Horse and carriage"let constantString = "Highlander"constantString += " and another Highlander"// 這會報告一個編譯錯誤 (compile-time error) - 常量不可以被修改。
注意:
在 Objective-C 和 Cocoa 中,您通過選擇兩個不同的類(NSString和NSMutableString)來指定該字串是否可以被修改,Swift 中的字串是否可以修改僅通過定義的是變數還是常量來決定,實現了多種類型可變性操作的統一。
字串是實值型別(Strings Are Value Types)
Swift 的String類型是實值型別。 如果您建立了一個新的字串,那麼當其進行常量、變數賦值操作或在函數/方法中傳遞時,會進行值拷貝。 任何情況下,都會對已有字串值建立新副本,並對該新副本進行傳遞或賦值操作。 實值型別在 結構體和枚舉是實值型別 中進行了說明。
注意:
與 Cocoa 中的NSString不同,當您在 Cocoa 中建立了一個NSString執行個體,並將其傳遞給一個函數/方法,或者賦值給一個變數,您傳遞或賦值的是該NSString執行個體的一個引用,除非您特別要求進行值拷貝,否則字串不會產生新的副本來進行賦值操作。
Swift 預設字串拷貝的方式保證了在函數/方法中傳遞的是字串的值。 很明顯無論該值來自於哪裡,都是您獨自擁有的。 您可以放心您傳遞的字串本身不會被更改。
在實際編譯時間,Swift 編譯器會最佳化字串的使用,使實際的複製只發生在絕對必要的情況下,這意味著您將字串作為實值型別的同時可以獲得極高的效能。
使用字元(Working with Characters)
Swift 的String類型表示特定序列的Character(字元) 類型值的集合。 每一個字元值代表一個 Unicode 字元。 您可利用for-in迴圈來遍曆字串中的每一個字元:
for character in "Dog!??" { println(character)}// D// o// g// !// ??
for-in 迴圈在 For Loops 中進行了詳細描述。
另外,通過標明一個Character類型註解並通過字元字面量進行賦值,可以建立一個獨立的字元常量或變數:
let yenSign: Character = "¥"
計算字元數量 (Counting Characters)
通過調用全域countElements函數,並將字串作為參數進行傳遞,可以擷取該字串的字元數量。
let unusualMenagerie = "Koala ??, Snail ??, Penguin ??, Dromedary ??"println("unusualMenagerie has \(countElements(unusualMenagerie)) characters")// 列印輸出:"unusualMenagerie has 40 characters"
注意:
不同的 Unicode 字元以及相同 Unicode 字元的不同表示方式可能需要不同數量的記憶體空間來儲存。所以 Swift 中的字元在一個字串中並不一定佔用相同的記憶體空間。因此字串的長度不得不通過迭代字串中每一個字元的長度來進行計算。如果您正在處理一個長字串,需要注意countElements函數必須遍曆字串中的字元以精準計算字串的長度。 另外需要注意的是通過countElements返回的字元數量並不總是與包含相同字元的NSString的length屬性相同。NSString的length屬性是基於利用 UTF-16 表示的十六位代碼單元數字,而不是基於 Unicode 字元。為瞭解決這個問題,NSString的length屬性在被 Swift 的String訪問時會成為utf16count。
連接字串和字元 (Concatenating Strings and Characters)
字串可以通過加法運算子(+)相加在一起(或稱“串聯”)並建立一個新的字串:
let string1 = "hello"let string2 = " there"var welcome = string1 + string2// welcome 現在等於 "hello there"
您也可以通過加法賦值運算子 (+=) 將一個字串添加到一個已經存在字串變數上:
var instruction = "look over"instruction += string2// instruction 現在等於 "look over there"
你可以用將append方法將一個字元附加到一個字串變數的尾部:
let exclamationMark: Character = "!"welcome.append(exclamationMark)// welcome 現在等於 "hello there!"
注意:
您不能將一個字串或者字元添加到一個已經存在的字元變數上,因為字元變數只能包含一個字元。
字串插值 (String Interpolation)
字串插值是一種構建新字串的方式,可以在其中包含常量、變數、字面量和運算式。 您插入的字串字面量的每一項都被包裹在以反斜線為首碼的圓括弧中:
let multiplier = 3let message = "\(multiplier) 乘以 2.5 是 \(Double(multiplier) * 2.5)"// message 是 "3 乘以 2.5 是 7.5"
在上面的例子中,multiplier作為\(multiplier)被插入到一個字串字面量中。 當建立字串執行插值計算時此預留位置會被替換為multiplier實際的值。
multiplier的值也作為字串中後面運算式的一部分。 該運算式計算Double(multiplier) * 2.5的值並將結果 (7.5) 插入到字串中。 在這個例子中,運算式寫為\(Double(multiplier) * 2.5)並包含在字串字面量中。
注意:
插值字串中寫在括弧中的運算式不能包含非轉義雙引號 (") 和反斜線 (\),並且不能包含斷行符號或分行符號。
比較字串 (Comparing Strings)
Swift 提供了三種方式來比較字串的值:字串相等、首碼相等和尾碼相等。
字串相等 (String Equality)
如果兩個字串以同一順序包含完全相同的字元,則認為兩者字串相等:
let quotation = "我們是一樣一樣滴."let sameQuotation = "我們是一樣一樣滴."if quotation == sameQuotation { println("這兩個字串被認為是相同的")}// 列印輸出:"這兩個字串被認為是相同的"
首碼/尾碼相等 (Prefix and Suffix Equality)
通過調用字串的hasPrefix/hasSuffix方法來檢查字串是否擁有特定首碼/尾碼。 兩個方法均需要以字串作為參數傳入並傳出Boolean值。 兩個方法均執行基底字元串和首碼/尾碼字串之間逐個字元的比較操作。
下面的例子以一個字串數組表示莎士比亞話劇《羅密歐與朱麗葉》中前兩場的情境位置:
let romeoAndJuliet = [ "Act 1 Scene 1: Verona, A public place", "Act 1 Scene 2: Capulet‘s mansion", "Act 1 Scene 3: A room in Capulet‘s mansion", "Act 1 Scene 4: A street outside Capulet‘s mansion", "Act 1 Scene 5: The Great Hall in Capulet‘s mansion", "Act 2 Scene 1: Outside Capulet‘s mansion", "Act 2 Scene 2: Capulet‘s orchard", "Act 2 Scene 3: Outside Friar Lawrence‘s cell", "Act 2 Scene 4: A street in Verona", "Act 2 Scene 5: Capulet‘s mansion", "Act 2 Scene 6: Friar Lawrence‘s cell"]
您可以利用hasPrefix方法來計算話劇中第一幕的情境數:
var act1SceneCount = 0for scene in romeoAndJuliet { if scene.hasPrefix("Act 1 ") { ++act1SceneCount }}println("There are \(act1SceneCount) scenes in Act 1")// 列印輸出:"There are 5 scenes in Act 1"
相似地,您可以用hasSuffix方法來計算髮生在不同地方的情境數:
var mansionCount = 0var cellCount = 0for scene in romeoAndJuliet { if scene.hasSuffix("Capulet‘s mansion") { ++mansionCount } else if scene.hasSuffix("Friar Lawrence‘s cell") { ++cellCount }}println("\(mansionCount) mansion scenes; \(cellCount) cell scenes")// 列印輸出:"6 mansion scenes; 2 cell scenes”
大寫和小寫字串(Uppercase and Lowercase Strings)
您可以通過字串的uppercaseString和lowercaseString屬性來訪問大寫/小寫版本的字串。
let normal = "Could you help me, please?"let shouty = normal.uppercaseString// shouty 值為 "COULD YOU HELP ME, PLEASE?"let whispered = normal.lowercaseString// whispered 值為 "could you help me, please?"
Unicode
Unicode 是一個國際標準,用於文本的編碼和表示。 它使您可以用標準格式表示來自任意語言幾乎所有的字元,並能夠對文字檔或網頁這樣的外部資源中的字元進行讀寫操作。
Swift 的字串和字元類型是完全相容 Unicode 標準的,它支援如下所述的一系列不同的 Unicode 編碼。
Unicode 術語(Unicode Terminology)
Unicode 中每一個字元都可以被解釋為一個或多個 unicode 標量。 字元的 unicode 標量是一個唯一的21位元字(和名稱),例如U+0061表示小寫拉丁字母A ("a"),U+1F425表示小雞表情 ("??")
當 Unicode 字串被寫進文字檔或其他儲存結構當中,這些 unicode 標量將會按照 Unicode 定義的集中格式之一進行編碼。其包括UTF-8(以8位代碼單元進行編碼) 和UTF-16(以16位代碼單元進行編碼)。
字串的 Unicode 表示(Unicode Representations of Strings)
Swift 提供了幾種不同的方式來訪問字串的 Unicode 表示。
您可以利用for-in來對字串進行遍曆,從而以 Unicode 字元的方式訪問每一個字元值。 該過程在 使用字元 中進行了描述。
另外,能夠以其他三種 Unicode 相容的方式訪問字串的值:
- UTF-8 代碼資料格集合 (利用字串的
utf8屬性進行訪問)
- UTF-16 代碼資料格集合 (利用字串的
utf16屬性進行訪問)
- 21位的 Unicode 標量值集合 (利用字串的
unicodeScalars屬性進行訪問)
下面由D``o``g``!和??(DOG FACE,Unicode 標量為U+1F436)組成的字串中的每一個字元代表著一種不同的表示:
let dogString = "Dog!??"
UTF-8
您可以通過遍曆字串的utf8屬性來訪問它的UTF-8表示。 其為UTF8View類型的屬性,UTF8View是無符號8位 (UInt8) 值的集合,每一個UInt8值都是一個字元的 UTF-8 表示:
for codeUnit in dogString.utf8 { print("\(codeUnit) ")}print("\n")// 68 111 103 33 240 159 144 182
上面的例子中,前四個10進位代碼單元值 (68, 111, 103, 33) 代表了字元D o g和!,它們的 UTF-8 表示與 ASCII 表示相同。 後四個代碼單元值 (240, 159, 144, 182) 是DOG FACE的4位元組 UTF-8 表示。
UTF-16
您可以通過遍曆字串的utf16屬性來訪問它的UTF-16表示。 其為UTF16View類型的屬性,UTF16View是無符號16位 (UInt16) 值的集合,每一個UInt16都是一個字元的 UTF-16 表示:
for codeUnit in dogString.utf16 { print("\(codeUnit) ")}print("\n")// 68 111 103 33 55357 56374
同樣,前四個代碼單元值 (68, 111, 103, 33) 代表了字元D o g和!,它們的 UTF-16 代碼單元和 UTF-8 完全相同。
第五和第六個代碼單元值 (55357 和 56374) 是DOG FACE字元的UTF-16 表示。 第一個值為U+D83D(十進位值為 55357),第二個值為U+DC36(十進位值為 56374)。
Unicode 標量 (Unicode Scalars)
您可以通過遍曆字串的unicodeScalars屬性來訪問它的 Unicode 標量表示。 其為UnicodeScalarView類型的屬性, UnicodeScalarView是UnicodeScalar的集合。 UnicodeScalar是21位的 Unicode 代碼點。
每一個UnicodeScalar擁有一個值屬性,可以返回對應的21位元值,用UInt32來表示。
for scalar in dogString.unicodeScalars { print("\(scalar.value) ")}print("\n")// 68 111 103 33 128054
同樣,前四個代碼單元值 (68, 111, 103, 33) 代表了字元D o g和!。 第五位元值,128054,是一個十六進位1F436的十進位表示。 其等同於DOG FACE的Unicode 標量 U+1F436。
作為查詢字元值屬性的一種替代方法,每個UnicodeScalar值也可以用來構建一個新的字串值,比如在字串插值中使用:
for scalar in dogString.unicodeScalars { println("\(scalar) ")}// D// o// g// !// ??
轉載:http://numbbbbb.gitbooks.io/-the-swift-programming-language-/chapter2/03_Strings_and_Characters.html
字串和字元(Strings and Characters)