字符串是一系列字符翘狱,如“hello, world”或“albatross”汞斧。Swift字符串由字符串類型表示生真。字符串的內(nèi)容可以通過多種方式訪問,包括作為字符值的集合吏祸。
Swift的字符串和字符類型提供了一種快速的对蒲、與unicode兼容的方式來處理代碼中的文本。字符串的語法創(chuàng)建和操縱輕便,可讀性強,與字符串的語法類似于c字符串連接非常簡單,只需將兩個字符串+操作符,和字符串可變性由常量或變量之間選擇,就像任何其他價值迅速贡翘。您還可以使用字符串將常量蹈矮、變量、文字和表達式插入到更長的字符串中鸣驱,這個過程稱為字符串插值泛鸟。這使得創(chuàng)建用于顯示、存儲和打印的自定義字符串值變得很容易踊东。
盡管語法簡單北滥,Swift的字符串類型是一種快速刚操、現(xiàn)代的字符串實現(xiàn)。每個字符串都由獨立于編碼的Unicode字符組成再芋,并支持以各種Unicode表示訪問這些字符菊霜。
Swift的字符串類型由Foundation的NSString類橋接。Foundation還擴展了String以公開NSString定義的方法济赎。這意味著鉴逞,如果你導(dǎo)入Foundation,你可以在String上訪問那些NSString方法而不用強制轉(zhuǎn)換司训。
String Literals 字符串文字
您可以在代碼中包含預(yù)定義的字符串值作為字符串文本构捡。字符串文字是由一對雙引號(")包圍的字符序列。
let someString = "Some string literal value"
注意豁遭,Swift推斷someString常量的字符串類型叭喜,因為它是用字符串文字值初始化的。
Multiline String Literals 多行字符串文字
如果您需要一個跨多行字符串蓖谢,請使用多行字符串—由三對雙引號"包圍的字符序列:
let quotation = """
The White Rabbit put on his spectacles. "Where shall I begin,
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on
till you come to the end; then stop."
"""
多行字符串文字包含其開始和結(jié)束引號之間的所有行捂蕴。字符串在開始引號(""")后面的第一行開始,在結(jié)束引號之前的一行結(jié)束闪幽,這意味著下面的字符串都沒有以換行符開始或結(jié)束:
let singleLineString = "These are the same."
let multilineString = """
These are the same.
"""
在多行字符串字面量中啥辨,如果出現(xiàn)了換行,那么同樣出現(xiàn)在字符串的值中盯腌,如果您只需要在代碼中換行來增強可讀性溉知,不希望換行出現(xiàn)在字符串值中,就在上一行代碼的后面添加 反斜杠 \
let softWrappedQuotation = """
The White Rabbit put on his spectacles. "Where shall I begin, \
please your Majesty?" he asked.
"Begin at the beginning," the King said gravely, "and go on \
till you come to the end; then stop."
"""
如果要所有字面量都在一行的話腕够,可以在字面量的第一行和最后一行為空白行即可级乍。
let lineBreaks = """
This string starts with a line break.
It also ends with a line break.
haha
"""
打印結(jié)果如下:
"\nThis string starts with a line break.\nIt also ends with a line break.\n haha\n"
如果在多行符結(jié)束標簽"""前面有n個空格,那么每行字面量開頭也必須至少要有m(m>=n)個空格帚湘,不然會報錯玫荣,多余的空格(m-n)將包含在字符串值中。如下:
let linesWithIndentation = """
這將沒有空格開頭
這將有4個空格開頭
"""
print(linesWithIndentation)
打印如下:
這將沒有空格開頭
這將有4個空格開頭
字符串文字中的特殊字符
特殊字符:
- 轉(zhuǎn)義的特殊字符\0(空字符)大诸、\(反斜杠)捅厂、\t(水平制表符)、\n(換行)资柔、\r(回車)焙贷、"(雙引號)和'(單引號)
- 任意Unicode標量值,寫為\u{n}贿堰,其中n是1-8位十六進制數(shù)字(Unicode在下面的Unicode中討論)
下面的代碼顯示了這些特殊字符的四個示例辙芍。wiseWords常量包含兩個轉(zhuǎn)義的雙引號。$符號羹与、blackHeart和sparklingHeart常量演示了Unicode標量格式:
let wiseWords = "\"Imagination is more important than knowledge\" - Einstein"
// "Imagination is more important than knowledge" - Einstein
let dollarSign = "\u{24}" // $, Unicode scalar U+0024
let blackHeart = "\u{2665}" // ?, Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // ??, Unicode scalar U+1F496
輸入結(jié)果如下:
"Imagination is more important than knowledge" - Einstein
$
?
??
Initializing an Empty String 初始化空字符串
為了構(gòu)建一個更長的字符串沸手,可以先創(chuàng)建一個空字符串外遇,可以將空字符串賦值給一個變量,也可以使用String的初始化方法:
var emptyString = "" // empty string literal
var anotherEmptyString = String() // initializer syntax
// these two strings are both empty, and are equivalent to each other
判斷字符串是否為空字符串
if emptyString.isEmpty {
print("Nothing to see here")
}
// Prints "Nothing to see here"
String Mutability 字符串可變性
指定一個特定的字符串是可以修改的(modified 或者 mutated)是將其賦值給一個變量(var 聲明)契吉,而不是賦值給一個常量(let 聲明)
var variableString = "Horse"
variableString += " and carriage"
// variableString is now "Horse and carriage"
let constantString = "Highlander"
constantString += " and another Highlander"
// this reports a compile-time error - a constant string cannot be modified
Strings Are Value Types 字符串是值類型
Swift的String類型是值類型。如果您創(chuàng)建一個新的字符串值诡渴,當將該字符串值傳遞給函數(shù)或方法時捐晶,或者當將該字符串值分配給常量或變量時,將復(fù)制該字符串值妄辩。在每種情況下惑灵,都會創(chuàng)建現(xiàn)有字符串值的新副本,并傳遞或分配新副本眼耀,而不是原始版本英支。
Swift 的默認復(fù)制字符串行為確保了函數(shù)或方法傳遞了一個字符串值哮伟,確定您擁有那個明確的字符串值,不管它來自哪里池凄。您可以確信傳遞給您的字符串不會被修改,除非您親自修改它肿仑。
在幕后碎税,Swift的編譯器優(yōu)化了字符串的使用尤慰,因此只有在絕對必要時才會進行實際的復(fù)制雷蹂。這意味著當使用字符串作為值類型時萎河,您總是可以獲得很好的性能虐杯。
Working with Characters 使用字符
你可以通過for-in循環(huán)遍歷字符串來訪問字符串的各個字符值:
for character in "Dog!??" {
print(character)
}
// D
// o
// g
// !
// ??
或者擎椰,您可以通過提供字符類型注解达舒,從單字符字符串文本創(chuàng)建一個獨立的字符常量或變量:
let exclamationMark: Character = "!"
字符串值可以通過將一組字符值作為參數(shù)傳遞給它的初始化器來構(gòu)造:
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 now equals "hello there"
也可以使用 += 運算符將一個字符串值添加到已存在的字符串變量中:
var instruction = "look over"
instruction += string2
// instruction now equals "look over there"
也可以使用 String 的 append()方法連接字符串
let exclamationMark: Character = "!"
welcome.append(exclamationMark)
// welcome now equals "hello there!"
多行字符串拼接時注意:
let badStart = """
one
two
"""
let end = """
three
"""
print(badStart + end)
// Prints two lines:
// one
// twothree
let goodStart = """
one
two
"""
print(goodStart + end)
// Prints three lines:
// one
// two
// three
String Interpolation 字符串插值
字符串插值是一種通過將常量昨登、變量丰辣、文字和表達式的值包含在字符串文字中來構(gòu)造新字符串值的方法笙什。您可以在單行和多行字符串文字中使用字符串插值琐凭。使用 (name):
let multiplier = 3
let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)"
// message is "3 times 2.5 is 7.5"
Unicode 字符編碼標準
Unicode是一種國際標準胚吁,用于在不同的書寫系統(tǒng)中編碼囤采、表示和處理文本蕉毯。它使您能夠以標準化的形式表示任何語言中的幾乎任何字符代虾,并將這些字符讀寫到外部源(如文本文件或web頁面)或從外部源(如文本文件或web頁面)棉磨。Swift的字符串和字符類型完全符合unicode乘瓤,如本節(jié)所述衙傀。
Unicode Scalar Values 字符編碼標量值
在后臺统抬,Swift的原生字符串類型是由Unicode標量值構(gòu)建的聪建。Unicode標量值是一個獨特的21-bit數(shù)字字符或修飾符,如拉丁字母小寫字母a 表示為 U+0061,或 U+1F425 表示為小雞(“??”)金麸。
注意叔锐,并非所有21位Unicode標量值都分配給一個字符—有些標量保留給將來的分配或UTF-16編碼中使用。分配給字符的標量值通常也有一個名稱解取,如上面示例中的拉丁字母a和小雞寶寶禀苦。
Extended Grapheme Clusters 擴展字符集群
Swift字符類型的每個實例都表示一個擴展的圖形簇振乏。擴展的grapheme集群是由一個或多個Unicode標量組成的序列慧邮,這些標量(組合在一起)產(chǎn)生一個人類可讀的字符误澳。
這是一個例子忆谓。字符é表示為單個Unicode標量é(帶銳號的拉丁小字母e,或U+00E9)昙沦。然而桅滋,也可以使用字母e和'組合來表示:
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e followed by ?
// eAcute is é, combinedEAcute is é
擴展的grapheme集群是一種靈活的方法丐谋,可以將許多復(fù)雜的腳本字符表示為單個字符值泌豆。例如踪危,韓語字母表中的漢古音節(jié)可以表示為預(yù)組合序列或分解序列贞远。這兩種表示法都可以作為Swift中的一個字符值:
let precomposed: Character = "\u{D55C}" // ?
let decomposed: Character = "\u{1112}\u{1161}\u{11AB}" // ?, ?, ?
// precomposed is ?, decomposed is ?
還有許多如:
let enclosedEAcute: Character = "\u{E9}\u{20DD}"
// enclosedEAcute is é?
let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}"
// regionalIndicatorForUS is ????
Counting Characters 字符個數(shù)
若要檢索字符串中字符值的計數(shù),請使用字符串的count屬性:
let unusualMenagerie = "Koala ??, Snail ??, Penguin ??, Dromedary ??"
print("unusualMenagerie has \(unusualMenagerie.count) characters")
// Prints "unusualMenagerie has 40 characters"
注意袱结,Swift對字符值使用擴展字符集群意味著字符串連接和修改并不總是影響字符串的字符數(shù)垢夹。
如:
var word = "cafe"
print("the number of characters in \(word) is \(word.count)")
// Prints "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.count)")
// Prints "the number of characters in café is 4"
注意:
擴展的圖形簇可以由多個Unicode標量組成。這意味著不同的字符—以及相同字符的不同表示—可能需要不同的內(nèi)存來存儲噪漾。因此欣硼,Swift中的每個字符在字符串表示中占用的內(nèi)存并不相同诈胜。因此焦匈,如果不遍歷字符串以確定其擴展的grapheme集群邊界累魔,就無法計算字符串中的字符數(shù)垦写。如果您正在處理特別長的字符串值梯投,請注意count屬性必須遍歷整個字符串中的Unicode標量分蓖,以便確定該字符串的字符。
count屬性返回的字符數(shù)并不總是與包含相同字符的NSString的length屬性相同午磁。NSString的長度基于字符串的UTF-16表示中16位代碼單元的數(shù)量,而不是字符串中Unicode擴展的圖形簇的數(shù)量衙熔。
Accessing and Modifying a String 訪問和修改字符串
您可以通過字符串的方法和屬性或使用下標語法訪問和修改字符串。
String Indices 字符串索引
每個字符串值都有一個關(guān)聯(lián)的索引類型String痢甘。索引塞栅,它對應(yīng)于字符串中每個字符的位置放椰。
如上所述,不同的字符可能需要不同數(shù)量的內(nèi)存來存儲如蚜,因此错邦,為了確定哪個字符位于特定位置兴猩,必須從字符串的開始或結(jié)束遍歷每個Unicode標量讨勤。由于這個原因潭千,Swift字符串不能被整數(shù)值索引。
使用startIndex屬性訪問字符串的第一個字符的位置狈癞。endIndex屬性是字符串中最后一個字符之后的位置蝶桶。因此真竖,endIndex屬性不是字符串下標的有效參數(shù)。如果字符串是空的讨韭,startIndex和endIndex是相等的拐袜。
使用String的index(before:)和index(after:)方法訪問給定索引之前和之后的索引。要訪問離給定索引更遠的索引甜攀,可以使用index(_:offsetBy:)方法规阀,而不是多次調(diào)用這些方法之一歧胁。
可以使用下標語法訪問特定字符串索引上的字符喊巍。
let greeting = "Guten Tag!"
greeting[greeting.startIndex]
// G
greeting[greeting.index(before: greeting.endIndex)]
// !
greeting[greeting.index(after: greeting.startIndex)]
// u
let index = greeting.index(greeting.startIndex, offsetBy: 7)
greeting[index]
// a
試圖訪問字符串范圍之外的索引或字符串范圍之外索引中的字符將觸發(fā)運行時錯誤。
greeting[greeting.endIndex] // Error
greeting.index(after: greeting.endIndex) // Error
使用indexes屬性訪問字符串中單個字符的所有索引海洼。
for index in greeting.indices {
print("\(greeting[index]) ", terminator: "")
}
// Prints "G u t e n T a g ! "
注意:
您可以對任何符合集合協(xié)議的類型使用startIndex和endIndex屬性以及index(before:)、index(after:)和index(_:offsetBy:)方法。這包括如下所示的字符串帘腹,以及數(shù)組、字典和Set等集合類型球化。
Inserting and Removing 插入和移除
若要在指定索引處將單個字符插入字符串筒愚,請使用insert(_:at:)方法句伶,
若要在指定索引處插入另一個字符串的內(nèi)容考余,請使用insert(contentsOf:at:)方法。
var welcome = "hello"
welcome.insert("!", at: welcome.endIndex)
// welcome now equals "hello!"
welcome.insert(contentsOf: " there", at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there!"
要從指定索引處的字符串中刪除單個字符身冬,請使用remove(at:)方法,
要在指定范圍內(nèi)刪除子字符串樱哼,請使用removeSubrange(_:)方法:
welcome.remove(at: welcome.index(before: welcome.endIndex))
// welcome now equals "hello there"
let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndex
welcome.removeSubrange(range)
// welcome now equals "hello"
注意:您可以在任何符合RangeReplaceableCollection協(xié)議的類型上使用insert(:at:)、insert(contentsOf:at:)茄唐、remove(at:)和removeSubrange(:)方法。這包括如下所示的字符串蚁廓,以及數(shù)組、字典和Set等集合類型饭宾。
Substrings 子字符串
當您從字符串獲取子字符串時(例如看铆,使用下標或類似prefix(_:)的方法)纬傲,結(jié)果是子字符串的實例,而不是另一個字符串汁雷。Swift中的子字符串具有與字符串相同的大部分方法侠讯,這意味著可以像處理字符串一樣處理子字符串。然而溜嗜,與字符串不同的是,在對字符串執(zhí)行操作時土全,只使用子字符串的時間很短。當準備長時間存儲結(jié)果時幻件,將子字符串轉(zhuǎn)換為String的實例篱蝇。例如:
let greeting = "Hello, world!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let beginning = greeting[..<index]
// beginning is "Hello"
// Convert the result to a String for long-term storage.
let newString = String(beginning)
與字符串一樣麸塞,每個子字符串都有一個內(nèi)存區(qū)域奥此,其中存儲組成子字符串的字符稚虎。字符串和子字符串之間的區(qū)別在于,作為一種性能優(yōu)化,子字符串可以重用用于存儲原始字符串的部分內(nèi)存祭钉,或者用于存儲另一個子字符串的部分內(nèi)存慌核。(字符串也有類似的優(yōu)化,但是如果兩個字符串共享內(nèi)存,它們是相等的钾怔。)這種性能優(yōu)化意味著,在修改字符串或子字符串之前矾利,不必為復(fù)制內(nèi)存付出性能代價馋袜。如上所述男旗,子字符串不適合長期存儲——因為它們重用了原始字符串的存儲,只要使用它的任何子字符串欣鳖,就必須將整個原始字符串保存在內(nèi)存中察皇。
在上面的例子中,greeting是一個字符串什荣,這意味著它有一個存儲組成字符串的字符的內(nèi)存區(qū)域矾缓。因為begin是問候語的子字符串,所以它重用問候語使用的內(nèi)存稻爬。相反嗜闻,newString是字符串——當它從子字符串創(chuàng)建時,它有自己的存儲因篇。下圖顯示了這些關(guān)系:
字符串和子字符串都符合StringProtocol協(xié)議泞辐,這意味著字符串操作函數(shù)通常可以方便地接受StringProtocol值竞滓。您可以使用字符串或子字符串值調(diào)用這些函數(shù)咐吼。
Comparing Strings 比較字符串
Swift提供了三種比較文本值的方法:字符串和字符相等、前綴相等和后綴相等商佑。string and character equality, prefix equality, and suffix equality.
String and Character Equality 字符串和字符相等性
字符串和字符的比較可以使用 == 和 != 運算符進行比較
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")
}
// Prints "These two strings are considered equal"
如果兩個字符串值(或兩個字符值)的擴展圖素集群具有標準的等價性锯茄,則認為它們是相等的。如果擴展的圖形簇具有相同的語言含義和外觀茶没,那么它們在標準上是等價的肌幽,即使它們是由不同的Unicode標量在幕后組成的。
這兩個擴展的grapheme集群都是表示字符 é 的有效方法抓半,因此它們被認為是標準等價的:
// "Voulez-vous un café?" using LATIN SMALL LETTER E WITH ACUTE
let eAcuteQuestion = "Voulez-vous un caf\u{E9}?"
// "Voulez-vous un café?" using 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")
}
// Prints "These two strings are considered equal"
相反,拉丁大寫字母(U + 0041,或“A”),是用于英語,并不等同于斯拉夫字母大寫字母(U + 0410,或“А”),是俄語喂急。文字在視覺上很相似,但沒有相同的語言意義:
let latinCapitalLetterA: Character = "\u{41}"
let cyrillicCapitalLetterA: Character = "\u{0410}"
if latinCapitalLetterA != cyrillicCapitalLetterA {
print("These two characters are not equivalent.")
}
// Prints "These two characters are not equivalent."
注意:Swift中的字符串和字符比較對語言環(huán)境不敏感笛求。
Prefix and Suffix Equality 前綴和后綴相等
要檢查字符串是否具有特定的字符串前綴或后綴廊移,請調(diào)用字符串的hasPrefix(:)和hasSuffix(:)方法,這兩個方法都接受string類型的單個參數(shù)并返回一個布爾值探入。
下面的例子考慮一個字符串數(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"
]
你可以用hasPrefix(_:)方法和romeoAndJuliet數(shù)組一起計算該劇第一幕場景的數(shù)量:
var act1SceneCount = 0
for scene in romeoAndJuliet {
if scene.hasPrefix("Act 1 ") {
act1SceneCount += 1
}
}
print("There are \(act1SceneCount) scenes in Act 1")
// Prints "There are 5 scenes in Act 1"
同樣,使用hasSuffix(_:)方法計算發(fā)生在Capulet 's mansion和Friar Lawrence 's cell內(nèi)或周圍的場景數(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")
// Prints "6 mansion scenes; 2 cell scenes"
Unicode Representations of Strings 字符串的Unicode表示
當將Unicode字符串寫入文本文件或其他存儲中時蜂嗽,該字符串中的Unicode標量將以Unicode定義的幾種編碼形式之一進行編碼苗膝。每個表單都將字符串編碼為稱為代碼單元的小塊。其中包括UTF-8編碼形式(將字符串編碼為8位代碼單元)植旧、UTF-16編碼形式(將字符串編碼為16位代碼單元)和UTF-32編碼形式(將字符串編碼為32位代碼單元)辱揭。
Swift提供了幾種不同的方法來訪問字符串的Unicode表示。您可以使用for-in語句遍歷字符串病附,以訪問其作為Unicode擴展的grapheme集群的單個字符值
或者问窃,在其他三個unicode兼容的表示形式中訪問一個字符串值:
- UTF-8代碼單元的集合(使用字符串的utf8屬性訪問)
- UTF-16代碼單元的集合(使用字符串的utf16屬性訪問)
- 一組21位Unicode標量值,相當于字符串的UTF-32編碼形式(使用字符串的unicodeScalars屬性訪問)
下面的字符串使用不同的表達方式組成
let dogString = "Dog???"
UTF-8 Representation
通過遍歷字符串的utf8屬性胖喳,可以訪問字符串的UTF-8表示形式。此屬性的類型為String贮竟。UTF8View丽焊,它是一個無符號8位(UInt8)值的集合较剃,每個字節(jié)在字符串的UTF-8表示:
for codeUnit in dogString.utf8 {
print("\(codeUnit) ", terminator: "")
}
print("")
// Prints "68 111 103 226 128 188 240 159 144 182 "
在上面的示例中,前三個十進制碼元值(68,111,103)表示字符D技健、o和g写穴,其UTF-8表示與ASCII表示相同。接下來的三個十進制代碼單元值(226雌贱、128啊送、188)是雙感嘆號字符的三字節(jié)UTF-8表示形式。最后四個codeUnit值(240欣孤、159馋没、144、182)是DOG FACE字符的四字節(jié)UTF-8表示降传。
UTF-16 Representation
通過遍歷字符串的utf16屬性篷朵,可以訪問字符串的UTF-16表示形式。此屬性的類型為String婆排。UTF16View声旺,它是一個無符號16位(UInt16)值的集合,在字符串的UTF-16表示中段只,每個16位代碼單元對應(yīng)一個值:
同樣腮猖,前三個codeUnit值(68,111,103)表示字符D、o和g赞枕,它們的UTF-16代碼單元具有與字符串的UTF-8表示相同的值(因為這些Unicode標量表示ASCII字符)澈缺。
第四個codeUnit值(8252)是十六進制值203C的十進制等效值,它表示雙感嘆號字符的Unicode標量U+203C鹦赎。這個字符可以用UTF-16表示為單個代碼單元谍椅。
第五個和第六個codeUnit值(55357和56374)是一個UTF-16代理對,表示狗的面部字符古话。這些值是高代理值U+D83D(十進制值55357)和低代理值U+DC36(十進制值56374)雏吭。
Unicode Scalar Representation Unicode標量表示
通過遍歷字符串值的unicodeScalars屬性,可以訪問字符串值的Unicode標量表示形式陪踩。此屬性屬于UnicodeScalarView類型杖们,它是UnicodeScalar類型值的集合。
每個UnicodeScalar都有一個value屬性肩狂,返回標量的21位值摘完,用UInt32值表示:
for scalar in dogString.unicodeScalars {
print("\(scalar.value) ", terminator: "")
}
print("")
// Prints "68 111 103 8252 128054 "
前三個UnicodeScalar值(68,111,103)的值屬性再次表示字符D、o和g傻谁。
第四個codeUnit值(8252)同樣是十六進制值203C的十進制等效值孝治,它表示雙感嘆號字符的Unicode標量U+203C。
第五個也是最后一個UnicodeScalar的值屬性128054是十六進制值1F436的十進制等價物,它表示Unicode標量U+1F436用于DOG FACE字符谈飒。
除了查詢它們的值屬性岂座,每個UnicodeScalar值還可以用來構(gòu)造一個新的字符串值,比如字符串插值:
for scalar in dogString.unicodeScalars {
print("\(scalar) ")
}
// D
// o
// g
// ?
// ??