3.字符串/字符[Strings and Characters]

[The Swift Programming Language 中文版]
本頁包含內(nèi)容:

字符串字面量
初始化空字符串
字符串可變性
字符串是值類型
使用字符
連接字符串和字符
字符串插值
Unicode
計算字符數(shù)量
訪問和修改字符串
比較字符串
字符串的 Unicode 表示形式

String是例如"hello, world"吁朦,"albatross"這樣的有序的Character(字符)類型的值的集合茁瘦。通過String類型來表示。 一個String的內(nèi)容可以用許多方式讀取镀层,它包括一個Character值的集合。
創(chuàng)建和操作字符串的語法與 C 語言中字符串操作相似,輕量并且易讀后众。 字符串連接操作只需要簡單地通過+符號將兩個字符串相連即可放闺。與 Swift 中其他值一樣祟昭,能否更改字符串的值,取決于其被定義為常量還是變量怖侦。你也可以在字符串內(nèi)插過程中使用字符串插入常量篡悟、變量谜叹、字面量表達成更長的字符串,這樣可以很容易的創(chuàng)建自定義的字符串值搬葬,進行展示荷腊、存儲以及打印。
盡管語法簡易急凰,但String類型是一種快速女仰、現(xiàn)代化的字符串實現(xiàn)。 每一個字符串都是由編碼無關(guān)的 Unicode 字符組成抡锈,并支持訪問字符的多種 Unicode 表示形式(representations)疾忍。

注意:
Swift 的String類型與 Foundation NSString類進行了無縫橋接。就像 AnyObject類型 中提到的一樣床三,在使用 Cocoa 中的 Foundation 框架時一罩,您可以將創(chuàng)建的任何字符串的值轉(zhuǎn)換成NSString,并調(diào)用任意的NSString API撇簿。您也可以在任意要求傳入NSString實例作為參數(shù)的 API 中用String類型的值代替聂渊。 更多關(guān)于在 Foundation 和 Cocoa 中使用String的信息請查看 Using Swift with Cocoa and Objective-C (Swift 2.1)。

字符串字面量(String Literals)
您可以在您的代碼中包含一段預(yù)定義的字符串值作為字符串字面量补疑。字符串字面量是由雙引號 ("") 包裹著的具有固定順序的文本字符集歧沪。 字符串字面量可以用于為常量和變量提供初始值:

let someString = "Some string literal value"

注意someString常量通過字符串字面量進行初始化,Swift 會推斷該常量為String類型莲组。

注意: 更多關(guān)于在字符串字面量中使用特殊字符的信息诊胞,請查看 字符串字面量的特殊字符 。

初始化空字符串 (Initializing an Empty String)
要創(chuàng)建一個空字符串作為初始值锹杈,可以將空的字符串字面量賦值給變量撵孤,也可以初始化一個新的String實例:

var emptyString = ""               // 空字符串字面量
var anotherEmptyString = String()  // 初始化方法
// 兩個字符串均為空并等價。

您可以通過檢查其Bool類型的isEmpty屬性來判斷該字符串是否為空:

if emptyString.isEmpty {
    print("Nothing to see here")
}
// 打印輸出:"Nothing to see here"

字符串可變性 (String Mutability)
您可以通過將一個特定字符串分配給一個變量來對其進行修改竭望,或者分配給一個常量來保證其不會被修改:

var variableString = "Horse"
variableString += " and carriage"
// variableString 現(xiàn)在為 "Horse and carriage"

let constantString = "Highlander"
constantString += " and another Highlander"
// 這會報告一個編譯錯誤 (compile-time error) - 常量字符串不可以被修改邪码。

注意: 在 Objective-C 和 Cocoa 中,您需要通過選擇兩個不同的類(NSString和NSMutableString)來指定字符串是否可以被修改咬清。

字符串是值類型(Strings Are Value Types)
Swift 的String類型是值類型闭专。 如果您創(chuàng)建了一個新的字符串,那么當(dāng)其進行常量旧烧、變量賦值操作影钉,或在函數(shù)/方法中傳遞時,會進行值拷貝掘剪。 任何情況下平委,都會對已有字符串值創(chuàng)建新副本,并對該新副本進行傳遞或賦值操作夺谁。 值類型在 結(jié)構(gòu)體和枚舉是值類型 中進行了詳細(xì)描述廉赔。

Swift 默認(rèn)字符串拷貝的方式保證了在函數(shù)/方法中傳遞的是字符串的值肉微。 很明顯無論該值來自于哪里,都是您獨自擁有的蜡塌。 您可以確信傳遞的字符串不會被修改碉纳,除非你自己去修改它。

在實際編譯時岗照,Swift 編譯器會優(yōu)化字符串的使用村象,使實際的復(fù)制只發(fā)生在絕對必要的情況下,這意味著您將字符串作為值類型的同時可以獲得極高的性能攒至。

使用字符(Working with Characters)
您可通過for-in循環(huán)來遍歷字符串中的characters屬性來獲取每一個字符的值:

for character in "Dog!??".characters {
    print(character)
}
// D
// o
// g
// !
// ??

for-in循環(huán)在 For 循環(huán) 中進行了詳細(xì)描述厚者。

另外,通過標(biāo)明一個Character類型并用字符字面量進行賦值迫吐,可以建立一個獨立的字符常量或變量:

let exclamationMark: Character = "!"

字符串可以通過傳遞一個值類型為Character的數(shù)組作為自變量來初始化:

let catCharacters: [Character] = ["C", "a", "t", "!", "??"]
let catString = String(catCharacters)
print(catString)
// 打印輸出:"Cat!??"

連接字符串和字符 (Concatenating Strings and Characters)
字符串可以通過加法運算符(+)相加在一起(或稱“連接”)創(chuàng)建一個新的字符串:

let string1 = "hello"
let string2 = " there"
var welcome = string1 + string2
// welcome 現(xiàn)在等于 "hello there"

您也可以通過加法賦值運算符 (+=) 將一個字符串添加到一個已經(jīng)存在字符串變量上:

var instruction = "look over"
instruction += string2
// instruction 現(xiàn)在等于 "look over there"

您可以用append()方法將一個字符附加到一個字符串變量的尾部:

let exclamationMark: Character = "!"
welcome.append(exclamationMark)
// welcome 現(xiàn)在等于 "hello there!"

注意: 您不能將一個字符串或者字符添加到一個已經(jīng)存在的字符變量上库菲,因為字符變量只能包含一個字符。

字符串插值 (String Interpolation)
字符串插值是一種構(gòu)建新字符串的方式志膀,可以在其中包含常量熙宇、變量、字面量和表達式溉浙。 您插入的字符串字面量的每一項都在以反斜線為前綴的圓括號中:

let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"

在上面的例子中烫止,multiplier作為(multiplier)被插入到一個字符串常量量中。 當(dāng)創(chuàng)建字符串執(zhí)行插值計算時此占位符會被替換為multiplier實際的值戳稽。

multiplier的值也作為字符串中后面表達式的一部分馆蠕。 該表達式計算Double(multiplier) * 2.5的值并將結(jié)果 (7.5) 插入到字符串中嫂丙。 在這個例子中瞻鹏,表達式寫為(Double(multiplier) * 2.5)并包含在字符串字面量中。

注意:
插值字符串中寫在括號中的表達式不能包含非轉(zhuǎn)義反斜杠 ()拟枚,并且不能包含回車或換行符颂郎。不過吼渡,插值字符串可以包含其他字面量。

Unicode
Unicode 是一個國際標(biāo)準(zhǔn)乓序,用于文本的編碼和表示寺酪。 它使您可以用標(biāo)準(zhǔn)格式表示來自任意語言幾乎所有的字符,并能夠?qū)ξ谋疚募蚓W(wǎng)頁這樣的外部資源中的字符進行讀寫操作替劈。 Swift 的String和Character類型是完全兼容 Unicode 標(biāo)準(zhǔn)的寄雀。

Unicode 標(biāo)量(Unicode Scalars)

Swift 的String類型是基于 Unicode 標(biāo)量 建立的。 Unicode 標(biāo)量是對應(yīng)字符或者修飾符的唯一的21位數(shù)字抬纸,例如U+0061表示小寫的拉丁字母(LATIN SMALL LETTER A)("a")咙俩,U+1F425表示小雞表情(FRONT-FACING BABY CHICK) ("??")耿戚。

注意: Unicode 碼位(code poing) 的范圍是U+0000到U+D7FF或者U+E000到U+10FFFF湿故。Unicode 標(biāo)量不包括 Unicode 代理項(surrogate pair) 碼位阿趁,其碼位范圍是U+D800到U+DFFF。
注意不是所有的21位 Unicode 標(biāo)量都代表一個字符坛猪,因為有一些標(biāo)量是留作未來分配的脖阵。已經(jīng)代表一個典型字符的標(biāo)量都有自己的名字,例如上面例子中的LATIN SMALL LETTER A和FRONT-FACING BABY CHICK墅茉。

字符串字面量的特殊字符 (Special Characters in String Literals)

字符串字面量可以包含以下特殊字符:

轉(zhuǎn)義字符\0(空字符)命黔、\(反斜線)、\t(水平制表符)就斤、\n(換行符)悍募、\r(回車符)、"(雙引號)洋机、'(單引號)坠宴。
Unicode 標(biāo)量,寫成\u{n}(u為小寫)绷旗,其中n為任意一到八位十六進制數(shù)且可用的 Unicode 位碼喜鼓。
下面的代碼為各種特殊字符的使用示例。 wiseWords常量包含了兩個雙引號衔肢。 dollarSign庄岖、blackHeart和sparklingHeart常量演示了三種不同格式的 Unicode 標(biāo)量:

let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imageination is more important than knowledge" - Enistein
let dollarSign = "\u{24}"             // $, Unicode 標(biāo)量 U+0024
let blackHeart = "\u{2665}"           // ?, Unicode 標(biāo)量 U+2665
let sparklingHeart = "\u{1F496}"      // ??, Unicode 標(biāo)量 U+1F496

可擴展的字形群集(Extended Grapheme Clusters)

每一個 Swift 的Character類型代表一個可擴展的字形群。 一個可擴展的字形群是一個或多個可生成人類可讀的字符 Unicode 標(biāo)量的有序排列角骤。 舉個例子隅忿,字母é可以用單一的 Unicode 標(biāo)量é(LATIN SMALL LETTER E WITH ACUTE, 或者U+00E9)來表示。然而一個標(biāo)準(zhǔn)的字母e(LATIN SMALL LETTER E或者U+0065) 加上一個急促重音(COMBINING ACTUE ACCENT)的標(biāo)量(U+0301)启搂,這樣一對標(biāo)量就表示了同樣的字母é硼控。 這個急促重音的標(biāo)量形象的將e轉(zhuǎn)換成了é。

在這兩種情況中胳赌,字母é代表了一個單一的 Swift 的Character值牢撼,同時代表了一個可擴展的字形群。 在第一種情況疑苫,這個字形群包含一個單一標(biāo)量熏版;而在第二種情況,它是包含兩個標(biāo)量的字形群:

let eAcute: Character = "\u{E9}"                         // é
let combinedEAcute: Character = "\u{65}\u{301}"          // e 后面加上  ?
// eAcute 是 é, combinedEAcute 是 é

可擴展的字符群集是一個靈活的方法捍掺,用許多復(fù)雜的腳本字符表示單一的Character值撼短。 例如,來自朝鮮語字母表的韓語音節(jié)能表示為組合或分解的有序排列挺勿。 在 Swift 都會表示為同一個單一的Character值:

let precomposed: Character = "\u{D55C}"                  // ?
let decomposed: Character = "\u{1112}\u{1161}\u{11AB}"   // ?, ?, ?
// precomposed 是 ?, decomposed 是 ?

可拓展的字符群集可以使包圍記號(例如COMBINING ENCLOSING CIRCLE或者U+20DD)的標(biāo)量包圍其他 Unicode 標(biāo)量曲横,作為一個單一的Character值:

let enclosedEAcute: Character = "\u{E9}\u{20DD}"
// enclosedEAcute 是 é?

地域性指示符號的 Unicode 標(biāo)量可以組合成一個單一的Character值,例如REGIONAL INDICATOR SYMBOL LETTER U(U+1F1FA)和REGIONAL INDICATOR SYMBOL LETTER S(U+1F1F8):

let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}"
// regionalIndicatorForUS 是 ????

計算字符數(shù)量 (Counting Characters)
如果想要獲得一個字符串中Character值的數(shù)量,可以使用字符串的characters屬性的count屬性:

let unusualMenagerie = "Koala ??, Snail ??, Penguin ??, Dromedary ??"
print("unusualMenagerie has \(unusualMenagerie.characters.count) characters")
// 打印輸出 "unusualMenagerie has 40 characters"

注意在 Swift 中禾嫉,使用可拓展的字符群集作為Character值來連接或改變字符串時灾杰,并不一定會更改字符串的字符數(shù)量。

例如熙参,如果你用四個字符的單詞cafe初始化一個新的字符串艳吠,然后添加一個COMBINING ACTUE ACCENT(U+0301)作為字符串的結(jié)尾。最終這個字符串的字符數(shù)量仍然是4孽椰,因為第四個字符是é昭娩,而不是e:

var word = "cafe"
print("the number of characters in \(word) is \(word.characters.count)")
// 打印輸出 "the number of characters in cafe is 4"

word += "\u{301}"    // COMBINING ACUTE ACCENT, U+0301

print("the number of characters in \(word) is \(word.characters.count)")
// 打印輸出 "the number of characters in café is 4"

注意: 可擴展的字符群集可以組成一個或者多個 Unicode 標(biāo)量。這意味著不同的字符以及相同字符的不同表示方式可能需要不同數(shù)量的內(nèi)存空間來存儲黍匾。所以 Swift 中的字符在一個字符串中并不一定占用相同的內(nèi)存空間數(shù)量栏渺。因此在沒有獲取字符串的可擴展的字符群的范圍時候,就不能計算出字符串的字符數(shù)量锐涯。如果您正在處理一個長字符串迈嘹,需要注意characters屬性必須遍歷全部的 Unicode 標(biāo)量,來確定字符串的字符數(shù)量全庸。

另外需要注意的是通過characters屬性返回的字符數(shù)量并不總是與包含相同字符的NSString的length屬性相同秀仲。NSString的length屬性是利用 UTF-16 表示的十六位代碼單元數(shù)字,而不是 Unicode 可擴展的字符群集壶笼。作為佐證神僵,當(dāng)一個NSString的length屬性被一個Swift的String值訪問時,實際上是調(diào)用了utf16Count覆劈。

訪問和修改字符串 (Accessing and Modifying a String)
你可以通過字符串的屬性和方法來訪問和修改它保礼,當(dāng)然也可以用下標(biāo)語法完成。

字符串索引 (String Indices)

每一個String值都有一個關(guān)聯(lián)的索引(index)類型责语,String.Index炮障,它對應(yīng)著字符串中的每一個Character的位置。

前面提到坤候,不同的字符可能會占用不同數(shù)量的內(nèi)存空間胁赢,所以要知道Character的確定位置,就必須從String開頭遍歷每一個 Unicode 標(biāo)量直到結(jié)尾白筹。因此智末,Swift 的字符串不能用整數(shù)(integer)做索引。

使用startIndex屬性可以獲取一個String的第一個Character的索引徒河。使用endIndex屬性可以獲取最后一個Character的后一個位置的索引系馆。因此,endIndex屬性不能作為一個字符串的有效下標(biāo)顽照。如果String是空串由蘑,startIndex和endIndex是相等的。

通過調(diào)用String.Index的predecessor()方法,可以立即得到前面一個索引尼酿,調(diào)用successor()方法可以立即得到后面一個索引下隧。任何一個String的索引都可以通過鎖鏈作用的這些方法來獲取另一個索引,也可以調(diào)用advancedBy(_:)方法來獲取谓媒。但如果嘗試獲取出界的字符串索引,就會拋出一個運行時錯誤何乎。

你可以使用下標(biāo)語法來訪問String特定索引的Character句惯。

let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.endIndex.predecessor()]
// !
greeting[greeting.startIndex.successor()]
// u
let index = greeting.startIndex.advancedBy(7)
greeting[index]
// a

試圖獲取越界索引對應(yīng)的Character,將引發(fā)一個運行時錯誤支救。

greeting[greeting.endIndex] // error
greeting.endIndex.successor() // error

使用characters屬性的indices屬性會創(chuàng)建一個包含全部索引的范圍(Range)抢野,用來在一個字符串中訪問單個字符。

for index in greeting.characters.indices {
   print("\(greeting[index]) ", terminator: "")
}
// 打印輸出 "G u t e n   T a g ! "

插入和刪除 (Inserting and Removing)

調(diào)用insert(_:atIndex:)方法可以在一個字符串的指定索引插入一個字符各墨。

var welcome = "hello"
welcome.insert("!", atIndex: welcome.endIndex)
// welcome now 現(xiàn)在等于 "hello!"

調(diào)用insertContentsOf(_:at:)方法可以在一個字符串的指定索引插入一個字符串指孤。

welcome.insertContentsOf(" there".characters, at: welcome.endIndex.predecessor())
// welcome 現(xiàn)在等于 "hello there!"

調(diào)用removeAtIndex(_:)方法可以在一個字符串的指定索引刪除一個字符。

welcome.removeAtIndex(welcome.endIndex.predecessor())
// welcome 現(xiàn)在等于 "hello there"

調(diào)用removeRange(_:)方法可以在一個字符串的指定索引刪除一個子字符串贬堵。

let range = welcome.endIndex.advancedBy(-6)..<welcome.endIndex
welcome.removeRange(range)
// welcome 現(xiàn)在等于 "hello"

比較字符串 (Comparing Strings)
Swift 提供了三種方式來比較文本值:字符串字符相等恃轩、前綴相等和后綴相等。

字符串/字符相等 (String and Character Equality)
字符串/字符可以用等于操作符(==)和不等于操作符(!=)黎做,詳細(xì)描述在比較運算符:

let quotation = "We're a lot alike, you and I."
let sameQuotation = "We're a lot alike, you and I."
if quotation == sameQuotation {
    print("These two strings are considered equal")
}
// 打印輸出 "These two strings are considered equal"

如果兩個字符串(或者兩個字符)的可擴展的字形群集是標(biāo)準(zhǔn)相等的叉跛,那就認(rèn)為它們是相等的。在這個情況下蒸殿,即使可擴展的字形群集是有不同的 Unicode 標(biāo)量構(gòu)成的筷厘,只要它們有同樣的語言意義和外觀,就認(rèn)為它們標(biāo)準(zhǔn)相等宏所。

例如酥艳,LATIN SMALL LETTER E WITH ACUTE(U+00E9)就是標(biāo)準(zhǔn)相等于LATIN SMALL LETTER E(U+0065)后面加上COMBINING ACUTE ACCENT(U+0301)。這兩個字符群集都是表示字符é的有效方式爬骤,所以它們被認(rèn)為是標(biāo)準(zhǔn)相等的:

// "Voulez-vous un café?" 使用 LATIN SMALL LETTER E WITH ACUTE
let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"

// "Voulez-vous un café?" 使用 LATIN SMALL LETTER E and COMBINING ACUTE ACCENT
let combinedEAcuteQuestion = "Voulez-vous un caf\u{65}\u{301}?"

if eAcuteQuestion == combinedEAcuteQuestion {
    print("These two strings are considered equal")
}
// 打印輸出 "These two strings are considered equal"

相反充石,英語中的LATIN CAPITAL LETTER A(U+0041,或者A)不等于俄語中的CYRILLIC CAPITAL LETTER A(U+0410霞玄,或者A)赫冬。兩個字符看著是一樣的,但卻有不同的語言意義:

let latinCapitalLetterA: Character = "\u{41}"

let cyrillicCapitalLetterA: Character = "\u{0410}"

if latinCapitalLetterA != cyrillicCapitalLetterA {
    print("These two characters are not equivalent")
}
// 打印 "These two characters are not equivalent"

注意: 在 Swift 中溃列,字符串和字符并不區(qū)分地域(not locale-sensitive)劲厌。

前綴/后綴相等 (Prefix and Suffix Equality)

通過調(diào)用字符串的hasPrefix(:)/hasSuffix(:)方法來檢查字符串是否擁有特定前綴/后綴,兩個方法均接收一個String類型的參數(shù)听隐,并返回一個布爾值补鼻。

下面的例子以一個字符串?dāng)?shù)組表示莎士比亞話劇《羅密歐與朱麗葉》中前兩場的場景位置:

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"
]

您可以調(diào)用hasPrefix(_:)方法來計算話劇中第一幕的場景數(shù):

var act1SceneCount = 0
for scene in romeoAndJuliet {
    if scene.hasPrefix("Act 1 ") {
        act1SceneCount += 1
    }
}
print("There are \(act1SceneCount) scenes in Act 1")
// 打印輸出 "There are 5 scenes in Act 1"

相似地,您可以用hasSuffix(_:)方法來計算發(fā)生在不同地方的場景數(shù):

var mansionCount = 0
var cellCount = 0
for scene in romeoAndJuliet {
    if scene.hasSuffix("Capulet's mansion") {
        mansionCount += 1
    } else if scene.hasSuffix("Friar Lawrence's cell") {
        cellCount += 1
    }
}
print("\(mansionCount) mansion scenes; \(cellCount) cell scenes")
// 打印輸出 "6 mansion scenes; 2 cell scenes"

注意: hasPrefix(:)和hasSuffix(:)方法都是在每個字符串中逐字符比較其可擴展的字符群集是否標(biāo)準(zhǔn)相等,詳細(xì)描述在字符串/字符相等风范。

字符串的 Unicode 表示形式(Unicode Representations of Strings)
當(dāng)一個 Unicode 字符串被寫進文本文件或者其他儲存時咨跌,字符串中的 Unicode 標(biāo)量會用 Unicode 定義的幾種編碼格式(encoding forms)編碼。每一個字符串中的小塊編碼都被稱代碼單元(code units)硼婿。這些包括 UTF-8 編碼格式(編碼字符串為8位的代碼單元)锌半, UTF-16 編碼格式(編碼字符串位16位的代碼單元),以及 UTF-32 編碼格式(編碼字符串32位的代碼單元)寇漫。

Swift 提供了幾種不同的方式來訪問字符串的 Unicode 表示形式刊殉。 您可以利用for-in來對字符串進行遍歷,從而以 Unicode 可擴展的字符群集的方式訪問每一個Character值州胳。 該過程在 使用字符 中進行了描述记焊。

另外,能夠以其他三種 Unicode 兼容的方式訪問字符串的值:

UTF-8 代碼單元集合 (利用字符串的utf8屬性進行訪問)
UTF-16 代碼單元集合 (利用字符串的utf16屬性進行訪問)
21位的 Unicode 標(biāo)量值集合栓撞,也就是字符串的 UTF-32 編碼格式 (利用字符串的unicodeScalars屬性進行訪問)
下面由D,o,g,?(DOUBLE EXCLAMATION MARK, Unicode 標(biāo)量 U+203C)和??(DOG FACE遍膜,Unicode 標(biāo)量為U+1F436)組成的字符串中的每一個字符代表著一種不同的表示:

let dogString = "Dog???"

UTF-8 表示

您可以通過遍歷String的utf8屬性來訪問它的UTF-8表示。 其為String.UTF8View類型的屬性瓤湘,UTF8View是無符號8位 (UInt8) 值的集合瓢颅,每一個UInt8值都是一個字符的 UTF-8 表示:

UTF-8
for codeUnit in dogString.utf8 {
    print("\(codeUnit) ", terminator: "")
}
print("")
// 68 111 103 226 128 188 240 159 144 182

上面的例子中,前三個10進制codeUnit值 (68, 111, 103) 代表了字符D弛说、o和 g惜索,它們的 UTF-8 表示與 ASCII 表示相同。 接下來的三個10進制codeUnit值 (226, 128, 188) 是DOUBLE EXCLAMATION MARK的3字節(jié) UTF-8 表示剃浇。 最后的四個codeUnit值 (240, 159, 144, 182) 是DOG FACE的4字節(jié) UTF-8 表示巾兆。

UTF-16 表示

您可以通過遍歷String的utf16屬性來訪問它的UTF-16表示。 其為String.UTF16View類型的屬性虎囚,UTF16View是無符號16位 (UInt16) 值的集合角塑,每一個UInt16都是一個字符的 UTF-16 表示:


UTF-16.png
for codeUnit in dogString.utf16 {
    print("\(codeUnit) ", terminator: "")
}
print("")
// 68 111 103 8252 55357 56374

同樣,前三個codeUnit值 (68, 111, 103) 代表了字符D淘讥、o和g圃伶,它們的 UTF-16 代碼單元和 UTF-8 完全相同(因為這些 Unicode 標(biāo)量表示 ASCII 字符)。

第四個codeUnit值 (8252) 是一個等于十六進制203C的的十進制值蒲列。這個代表了DOUBLE EXCLAMATION MARK字符的 Unicode 標(biāo)量值U+203C窒朋。這個字符在 UTF-16 中可以用一個代碼單元表示。

第五和第六個codeUnit值 (55357和56374) 是DOG FACE字符的 UTF-16 表示蝗岖。 第一個值為U+D83D(十進制值為55357)侥猩,第二個值為U+DC36(十進制值為56374)。

Unicode 標(biāo)量表示 (Unicode Scalars Representation)

您可以通過遍歷String值的unicodeScalars屬性來訪問它的 Unicode 標(biāo)量表示抵赢。 其為UnicodeScalarView類型的屬性欺劳,UnicodeScalarView是UnicodeScalar類型的值的集合唧取。 UnicodeScalar是21位的 Unicode 代碼點。

每一個UnicodeScalar擁有一個value屬性划提,可以返回對應(yīng)的21位數(shù)值枫弟,用UInt32來表示:

UTF-32
for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ", terminator: "")
}
print("")
// 68 111 103 8252 128054

前三個UnicodeScalar值(68, 111, 103)的value屬性仍然代表字符D、o和g鹏往。 第四個codeUnit值(8252)仍然是一個等于十六進制203C的十進制值淡诗。這個代表了DOUBLE EXCLAMATION MARK字符的 Unicode 標(biāo)量U+203C。

第五個UnicodeScalar值的value屬性伊履,128054韩容,是一個十六進制1F436的十進制表示。其等同于DOG FACE的 Unicode 標(biāo)量U+1F436湾碎。

作為查詢它們的value屬性的一種替代方法,每個UnicodeScalar值也可以用來構(gòu)建一個新的String值奠货,比如在字符串插值中使用:

for scalar in dogString.unicodeScalars {
    print("\(scalar) ")
}
// D
// o
// g
// ?
// ??
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末介褥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子递惋,更是在濱河造成了極大的恐慌柔滔,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萍虽,死亡現(xiàn)場離奇詭異睛廊,居然都是意外死亡,警方通過查閱死者的電腦和手機杉编,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門超全,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人邓馒,你說我怎么就攤上這事嘶朱。” “怎么了光酣?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵疏遏,是天一觀的道長。 經(jīng)常有香客問我救军,道長财异,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任唱遭,我火速辦了婚禮戳寸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拷泽。我一直安慰自己庆揩,他們只是感情好俐东,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著订晌,像睡著了一般虏辫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上锈拨,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天砌庄,我揣著相機與錄音,去河邊找鬼奕枢。 笑死娄昆,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缝彬。 我是一名探鬼主播萌焰,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼谷浅!你這毒婦竟也來了扒俯?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤一疯,失蹤者是張志新(化名)和其女友劉穎撼玄,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體墩邀,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡掌猛,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了眉睹。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荔茬。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖竹海,靈堂內(nèi)的尸體忽然破棺而出兔院,到底是詐尸還是另有隱情,我是刑警寧澤站削,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布坊萝,位于F島的核電站,受9級特大地震影響许起,放射性物質(zhì)發(fā)生泄漏十偶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一园细、第九天 我趴在偏房一處隱蔽的房頂上張望惦积。 院中可真熱鬧,春花似錦猛频、人聲如沸狮崩。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽睦柴。三九已至诽凌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坦敌,已是汗流浹背侣诵。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狱窘,地道東北人杜顺。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像蘸炸,于是被迫代替她去往敵國和親躬络。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容