Swift 5.1 (3) - 字符串

級別: ★☆☆☆☆
標簽:「iOS」「Swift 5.1」「字符串」
作者: 沐靈洛
審校: QiShare團隊


字符串
字符串是一系列字符組成的。Swift字符串由String類型表示。
1.使用字符串文字作為常量或變量的初始值:

let str = "I am zhangfei"http://str 系統使用類型推斷為String類型

2.多行字符串:由三個雙引號"""括起來的字符序列。注意:多行字符串文字的正文開始以及結束時,分隔符"""必須獨占一行。

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."
"""
let multilineString = """
These are the same.
"""

多行字符串文字中包含換行符時,該換行符也會出現在字符串的值中。
如果只想使用換行符來簡化代碼的讀取,而不希望換行符成為字符串值的一部分,請在這些行的末尾寫一個反斜杠\

/*
 不加反斜杠\打印:
 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."
 加反斜杠\打印:
 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 ontill you come to the end; then stop."
 */
 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."
"""
print(softWrappedQuotation)

字符串中的特殊字符
字符串中可以包含以下特殊字符:

  • 轉義的特殊字符 \ 0(空字符),\\(反斜杠),\ t(水平制表符),\ n(換行符),\ r \ n(回車符),\"(雙引號)和\'(單
    引號)。
  • 一個任意的Unicode標量值,寫為\ u {n},其中n是1-8位十六進制數。

特殊字符示例:

let name = "i am \"張飛\""
let dollarSign = "\u{24}"        // $,  Unicode標量 U+0024
let blackHeart = "\u{2665}"      // ?,  Unicode標量 U+2665
let sparklingHeart = "\u{1F496}" // ??, Unicode標量 U+1F496
print(name+dollarSign+blackHeart+sparklingHeart)//!<i am "張飛"$???

因為多行字符串文字使用三個雙引號"""而不是一個",故多行字符串文字中包含雙引號"可以不用轉義它。但是要在多行字符串中包含""" ,需要至少轉義一個引號。

let threeDoubleQuotationMarks = """
Escaping the first quotation mark \"""
Escaping all three quotation marks \"\"\"
"""

擴展字符串分隔符: 我們可以將包含特殊字符的字符串放在擴展分隔符中,讓所包含的特殊字符(如:轉義符)不生效。使用時將字符串放在引號"中并用數字符號括起來。#的個數不限制,但是數量需要保持一致性。形式:let str = #"Line 1\nLine 2"#str輸出換行符\n而不是輸出兩行的字符串。
如果需要字符串中特殊字符的特殊效果,則需要在轉義字符\后面使用數字符號#,但要注意匹配#的個數。例如,字符串:let str = #"Line 1\nLine 2"#,我們需要讓換行符\n生效,則可以使用let str = #"Line 1\#nLine 2"#來代替。同樣,let str = ##"Line 1\##nLine 2"##let str = ###"Line 1\###nLine 2"###也能讓換行符生效。
多行字符串使用擴展分隔符而不需要使用轉義符\,例如:

let threeQuotationMarks = #"""
Here are three more double quotes: """
"""#
print(threeQuotationMarks)//!< log:Here are three more double quotes: """

初始化一個空的字符串: 可以使用將空字符串指定給變量,或使用初始化字符串的語法初始化一個String實例:

// 一下兩個字符串都是空的,并且彼此都是相等的
var emptyString = ""        
var anotherEmptyString = String() 

字符串判空:

if emptyString.isEmpty {
    print("空字符串")
}

可變字符串:將特定字符串賦值給變量或常量,來表示字符串是否可以被修改。
將特定字符串賦值給變量:在這種情況下可以對其進行修改。

var variableString = "Horse"
variableString += " and carriage"
print(variableString)

將特定字符串賦值給常量:在這種情況下無法對其進行修改。

let constantString = "Highlander"
constantString += " and another Highlander"http://!< 編譯器報錯:constantString是常量不可變

這種方法與Objective-C和Cocoa中的字符串可變不同,您可以在兩個類NSString和NSMutableString之間進行選擇,區分可變字符串。

字符串是值類型: Swift的String類型是一種值類型。如果我們創建一個新的字符串a,在將a傳遞給函數或方法時,或將其賦值給常量或變量時,將復制字符串a的值。在以上每種情況下,都會創建現有字符串的新副本,并傳遞或分配新副本,而不是原始字符串。
Swift默認復制字符串的行為,確保了在函數或方法中傳遞字符串時,該字符串的值不會被改變,無論它來自何處,除非我們自己修改。
同時Swift的編譯器對字符串的默認復制行為做了優化:只有在絕對必要的情況下才會進行實際的復制,保證了性能。

字符使用:我們可以通過使用for-in循環遍歷字符串來訪問字符串中各個字符。

let str = "Dog!"
for character in str {
    print(character)
}

創建一個Character類型的常量或變量

//創建常量
let character : Character = ""
print(character)
//創建變量
var character : Character = ""
character = ""
print(character)

通過字符數組,生成一個字符串

let catCharacters : [Character] = ["c","a","t","i","s",""]
let catString = String(catCharacters)
print(catString)

連接字符串和字符:
字符串可以使用加法運算符+連接到一起以創建新的字符串:

let string1 = "hello"
let string2 = " there"
let welcome = string1 + string2
print(welcome)

使用加號賦值運算符+=

var instruction = "look over"
let string2 = " there"
instruction += string2 //!< log:look over there

使用String類型的append()方法將Character類型的值添加到String類型的變量。

var character : Character = ""
character = ""
var instruction = "look over"
let string2 = " there"
instruction += string2
instruction.append(character) //!< look over there

使用多行字符串文字來構建更多行的字符串,則希望字符串中的每一行都以換行符結束,包括最后一行。

let badStart = """
one
two
"""
let end = """
three
"""
/*輸出兩行:badStart的最后一行不以換行符結束,所以該行與end的第一行結合
one
twothree
*/
print(badStart + end)

let goodStart = """
one
two

"""
/*輸出三行:goodStart最后一行以換行符結束。
one
two
three
*/
print(goodStart + end)

字符串插值:字符串插值是一種通過在字符串中混合常量,變量,文字和表達式并可以構造出新字符串的方法。
作用:將常量或變量的名稱包含在較長字符串中作為占位符,并提示Swift將其替換為該常量或變量的當前值。使用形式:將名稱括在括號中,并在左括號前用反斜杠轉義它\(變量或常量)。單行和多行字符串都可以使用字符串插值。

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

上例中\(multiplier)\(Double(multiplier) * 2.5)屬于字符串插值。

print(#"Write an interpolated string in Swift using \(multiplier)."#)//!<Write an interpolated string in Swift using \(multiplier).

上例中使用擴展字符串分隔符來創建包含特殊字符\的字符串,否則這些字符將被視為字符串插值。
若要在使用擴展分隔符的字符串中使用字符串插值,需將\后面的數字符號#的個數與字符串開頭和結尾處#的個數相匹配。

print(#"Write an interpolated string in Swift using \#(multiplier)."#)//!<Write an interpolated string in Swift using 3.

Unicode:又名:統一碼、萬國碼、單一碼。它是跨語言、跨平臺進行文本轉換、處理的國際標準。Swift中的字符串和字符類型完全符合Unicode。

  1. Unicode標量:Swift的原生String類型是根據Unicode標量構建的。Unicode標量:使用21個二進制位表示的字符或修飾符,(注解:目前Unicode的編碼范圍達到了21位,Unicode標量范圍 0x0000 - 0x10ffff 的范圍,二進制位為 1 0000 1111 1111 1111 1111,總共21位)例如:U+0061表示a,U+1F425表示??。需要注意的是,Unicode標量值并不需要把所有21個二進制位都分配給字符或修飾符 ,某些多出來的Unicode標量會保留下來,用于將來分配或用于UTF-16編碼(注解:UTF-16是Unicode的其中一個使用方式,即把Unicode字符集的抽象碼位映射為16位的序列,用于數據存儲或傳遞)。

  2. 擴展字形集群:Swift的Character類型的每個實例,代表一個擴展的字形集群。擴展字形集群是一個或多個可組合的Unicode標量(組合時,產生單個人類可讀字符)的序列。字母é可以表示為單個Unicode標量\u{00E9}。字母é也可以表示為一對標量 :標準字母e:\u{0065}和尖音符\u{301}組合的形式。(音調符標量以圖形方式應用于其前面的標量,當它由具有Unicode感知的文本渲染系統渲染時將e轉換為é)
    在這兩種情況下,字母é表示為單個Swift中的Character值,表示可擴展的字形簇。在第一種情況下,集群中的單個標量;在第二種情況下,它是兩個標量的集群:

let eAcute: Character = "\u{E9}"                         // é
let combinedEAcute: Character = "\u{65}\u{301}" //é
print(String(eAcute)+String(combinedEAcute))

可擴展的字形集群是一種將許多復雜腳本字符表示為單個字符值的靈活方式。

let precomposed: Character = "\u{D55C}"                  // ?
let decomposed: Character = "\u{1112}\u{1161}\u{11AB}"   // \u{1112}:?, \u{1161}:?,\u{11AB}: ? ->?
print(String(precomposed)+String(decomposed))

區域指示符號的Unicode標量可以成對組合以生成單個字符值,例如區域指示符符號U(U + 1F1FA)和區域指示符符號字母S(U + 1F1F8)的組合:

let regionalIndicatorForUS: Character = "\u{1F1FA}\u{1F1F8}"
print(String(regionalIndicatorForUS))//log:????

字符計數:檢索字符串中字符的數目,可以使用字符串的count屬性:

let title = "Koala ??, Snail ??, Penguin ??, Dromedary ??"
print("title中有\(title.count)個字符")//!< 40個字符

需要注意的是:Swift中對字符串拼接擴展字形集群可能并不會影響字符串的字符數目。如:

var x = "thing" //!< x.count = 5
x += "\u{301}" //!< x:thin?
print(x) //!< x.count 依舊是5

擴展的字形集群可以由多個Unicode標量組成。這意味著相同字符的不同表示可能需要不同的內存量來存儲。因此,在Swift中,字符串的每個字符在內存中所占的大小可能不相同。需要注意的是如果字符串特別長,使用count屬性獲取字符串中字符數量時,是會遍歷整個字符串中的Unicode標量的。count屬性可能與包含相同字符的NSString的length屬性返回的字符數量不相同。因為兩者的計算基準不一樣。NSString的長度基于字符串的UTF-16表示中的16位碼元的數量,而不是基于字符串中Unicode可擴展的字形集群的數量。

//OC中計算的字符數。
NSString *str = @"Koala ??, Snail ??, Penguin ??, Dromedary ??";
NSLog(@"%ld",str.length);//!< 44個字符

訪問和修改字符串:通過相應方法和屬性或使用下標語法來訪問和修改字符串。
字符串索引:每個String值都有一個關聯的索引類型String.Index,它對應于字符串中每個字符的位置。
如上所述,Swift中不同的字符可能需要不同的內存量來存儲,因為Swift的字符串中字符數是基于Unicode標量的來計算的:a.集群中的單個標量,b.多個標量的可擴展集群。因此Swift字符串不能用整數值索引,為了確定某個特定的字符位于哪個位置,我們必須從該字符串的開頭或結尾遍歷每個Unicode標量
使用startIndex屬性可以訪問字符串的第一個字符的位置。endIndex屬性是字符串最后一個字符之后的位置。因此,endIndex屬性不是字符串下標的有效參數。如果字符串為空,則startIndexendIndex相等。可以使用字符串的索引index(before: )index(after:)方法訪問給定索引之前和之后的索引。要訪問遠離給定索引的索引,可以使用索引index(_:, offsetBy: )方法,而不是多次調用其中一種方法。字符串title根據字符索引獲取字符:title[String.Index(必須是索引類型)]

let title = "Koala ??, Snail ??, Penguin ??, Dromedary ??"
let subStr = title[title.index(after: title.startIndex)]//!< startIndex之后的位置 輸出o
let subStr1 = title[title.index(before: title.endIndex)]//!< ??

let subStr2 = title[title.index(title.endIndex, offsetBy: -1)] //!< log:??
let subStr3 = title[title.index(title.startIndex, offsetBy: 6)]//!< log: ??

let index = title.index(title.startIndex, offsetBy: 15)
let subStr4 = title[index] //!< log:??

嘗試訪問字符串范圍之外的索引或字符時將觸發運行時錯誤。

//! 所得索引超越了字符串的有效范圍,觸發運行時錯誤:Thread 1: Fatal error: String index is out of bounds
let outsideIndex = title.index(after: title.endIndex)
//!索引超越了有效范圍,觸發運行時錯誤:Thread 1: Fatal error: String index is out of bounds
let subStr5 = title[title.endIndex]

使用indices屬性可以獲取字符串中所有字符的索引。

let indices = title.indices;//!DefaultIndices<String>(_elements: "Koala , Snail , Penguin , Dromedary ", _startIndex: Swift.String.Index(_rawBits: 0), _endIndex: Swift.String.Index(_rawBits: 3407872))
var tempStr:String = ""
for index in indices {
    print("\(title[index])","",separator: "_", terminator: "", to: &tempStr)
}
////!< 最終合成的新字符串:K_o_a_l_a_ __,_ _S_n_a_i_l_ __,_ _P_e_n_g_u_i_n_ __,_ _D_r_o_m_e_d_a_r_y_ __
print("最終合成的新字符串:\(tempStr)")

重點:我們可以在符合Collection協議的任何類型上使用startIndexendIndex屬性以及索引index(before: )index(after:)index(_:, offsetBy: )方法。這包括字符串以及集合類型,如Array,Dictionary和Set。
字符串插入和刪除:
插入:字符串指定索引處插入單個字符使用insert(_:at:)方法;在指定索引處插入另一個字符串使用insert(contentsOf:at:)方法。

var inserStr = "hello"
//! 插入單個字符:unicode標量
inserStr.insert("\u{1F1F7}", at: inserStr.startIndex)//!< log:??hello
//! 插入單個字符:普通字符
inserStr.insert("!", at: inserStr.endIndex)//!< log:??hello! 插入時可以使用endIndex
//!< 插入字符串:由字符:unicode標量組成的字符串
let scalarStr = "\u{1F1F6}\u{1F496}"http://!< ????
inserStr.insert(contentsOf: scalarStr, at: inserStr.startIndex)//!< ??????hello!
//! 插入普通字符串:
let normalStr = "_word"
inserStr.insert(contentsOf: normalStr, at: inserStr.index(before: inserStr.endIndex))//!< ??????hello_word!

刪除:字符串刪除指定索引處的單個字符使用remove(at:)方法;刪除指定范圍內的子字符串使用removeSubrange(_:)方法:

//復雜組成的字符串
var removeStr = "\u{1F1F6}\u{1E67F}\u{1F496}\u{1F1F7}hello_word!eye\u{301}"http://!< log:??????hello_word!eyé
//移除unicode標量字符:??
removeStr.remove(at: removeStr.index(removeStr.startIndex, offsetBy: 2))//!< log:????hello_word!eyé
//移除普通字符:y 為啥-2因為endIndex屬性表示字符串最后一個字符之后的位置
removeStr.remove(at: removeStr.index(removeStr.endIndex, offsetBy: -2))//!< log:????hello_word!eé
//!< 刪除子0-1范圍內的字符串:由字符:unicode標量組成的子字符串:??
//*range
//    let range = removeStr.startIndex..<removeStr.index(removeStr.startIndex, offsetBy: 2)
//或
let range = removeStr.startIndex...removeStr.index(removeStr.startIndex, offsetBy: 1)
removeStr.removeSubrange(range) //!< ??hello_word!eé

注意:String類型實現了RangeReplaceableCollection協議,其他實現了RangeReplaceableCollection協議的任何類型都可以使用insert(_:at:)insert(contentsOf:at:)remove(at:)removeSubrange(_:)方法。如:Array,Dictionary和Set。
子字符串:
從字符串中獲取子字符串時 - 例如,使用索引或類似prefix(_:)的方法 ,結果是Substring的實例,而不是另一個字符串。Swift中的子字符串與字符串具有多數相同的方法,這意味著我們可以像處理字符串一樣使用子字符串。但是與字符串不同,我們在對字符串執行操作時只會使用子字符串很短的時間。當我們需要將子字符串存儲更長時間時,則需要將子字符串轉換為String實例。

var myString = "\u{1F1F6}\u{1E67F}\u{1F496}\u{1F1F7}hello_word!eye\u{301}"http://!< log:??hello_word!eyé
//從字符串中取出hello子字符串
//1.獲取hello在字符中的范圍
//Returns the last index where the specified value appears in the collection.
let subStart = myString.lastIndex(of:"??" ) ?? myString.startIndex //!< 字符??的位置
//Returns the first index where the specified value appears in the collection.
let subEnd = myString.firstIndex(of: "_") ?? myString.endIndex//!< 字符_的位置
//2.獲取子字符串
let subString = myString[subStart..<subEnd]//!<log: ??hello
print(subString)
//3.若需要長時間使用子字符串則需要類型轉換
let longSubStr = String(subString) //!< or:String.init(subString)

重點知識:
字符串和子字符串之間的區別:與字符串一樣,每個子字符串都有一個內存區域,用于存儲構成子字符串的字符。但是作為性能優化,子字符串可以重用用于存儲原始字符串的部分內存,或者用于存儲另一個子字符串的內存的一部分。字符串具有類似的優化,但如果兩個字符串共享內存,則它們是相等的此性能優化意味著在修改字符串或子字符串之前,不會增加復制內存的性能成本。如上所述,子字符串不適合長期存儲 因為它們重用原始字符串的存儲,只要使用任何子字符串,整個原始字符串就必須保存在內存中
示例描述:myString是一個字符串,這意味著它有一個內存區域,用于存儲構成字符串的字符。因為subString是myString的子字符串,所以它重用了myString使用的內存。相比之下,longSubStr是一個字符串 ,從子字符串創建時,它有自己的存儲空間。

字符串和子字符串區別與聯系

字符串比較:
字符串和字符是否相等的比較:使用“等于”運算符==和“不等于”運算符!=檢查字符串和字符相等性。

let testStr1 = "i have a cat\u{E9}?"http://!< i have a caté?
let testStr2 = "i have a cat\u{65}\u{301}?"http://!< i have a caté?
if testStr1 == testStr2 {
    print("這兩個字符串是相等的")
}

如果兩個字符串值(或兩個字符值)的擴展字形集群在規范上等效,則它們被認為是相等的。如果擴展的字形集群具有相同的語言含義和外觀,則它們在規范上是等效的,即使它們是不同Unicode標量組成的。
舉個反例:英語中大寫字母A:\u{0041}不等同于俄語中的A:\u{0410}。字符在視覺上相同,但卻不具有相同的語言含義,因此也是不相等的。

let englishA = "\u{0041}"http://!< A
let RussianA = "\u{0410}"http://!< A
if englishA == RussianA {
    print("這兩個字符串是相等的")
} else {
    print("這兩個字符串是不相等的")//!< log:這兩個字符串是不相等的
}

字符串的前綴與后綴的比較:要檢查字符串是否具有特定的字符串前綴或后綴,調用字符串的hasPrefix(_ :)hasSuffix(_ :)方法,返回值都為布爾值。

let testStr1 = "i have a cat\u{E9}?"http://!< i have a caté?
let testStr2 = "i have a cat\u{65}\u{301}?"http://!< i have a caté?
let array = [testStr1,testStr2]
for item in array[...] {
    if item.hasPrefix("i") {
        print(item + "*")
    }
}
/*注意:hasPrefix(_ :)和hasSuffix(_ :)方法在每個字符串中的擴展字形集群之間執行逐個字符的規范等效比較。*/
for item in array[...] {
    if item.hasSuffix("\u{E9}?") {
        print(item + "*")//!<輸出兩次: i have a caté?*
    }
}

注意:在每個字符串中調用hasPrefix(_ :)hasSuffix(_ :)方法,會在字符串的擴展字形集群之間逐個字符進行規范的相等比較
字符串的Unicode表示:
將Unicode字符串寫入文本文件或其他存儲時,字符串中的Unicode標量將以多種Unicode定義的編碼方式之一進行編碼。每種編碼方式都是以碼元(二進制位)為單位對字符串進行編碼。
Unicode定義的編碼方式:1.UTF-8編碼格式:將字符串編碼為多個8個二進制位的碼元。2.UTF-16編碼格式:將字符串編碼為多個16個二進制位的碼元。3.UTF-32編碼格式:將字符串編碼為多個32個二進制位的碼元。
Swift提供了幾種訪問字符串的Unicode的方法。
a. 使用for-in語句迭代字符串,將其各個字符值作為Unicode擴展字符集群進行訪問。
b. 訪問字符串的值依據兼容Unicode的三種編碼方式之一。

  • UTF-8碼元的集合,使用字符串的utf8屬性訪問
  • UTF-16碼元的集合,使用字符串的utf16屬性訪問
  • 21位的Unicode標量值的集合,相當于字符串的UTF-32編碼格式,使用字符串的unicodeScalars屬性訪問。

1.UTF-8表示:
通過迭代字符串的utf8屬性來訪問字符串的UTF-8編碼格式的表示形式。utf8屬性的類型為String.UTF8View
關于String.UTF8View結構體:將字符串內容作為UTF-8碼元的集合進行展示。我們可以使用字符串utf8屬性訪問字符串的UTF-8碼元表示形式。String.UTF8View將字符串的Unicode標量值編碼為無符號的8位整數,故:String.UTF8View是無符號的8位整數UInt8值的集合 。字符串中Unicode標量值最長可達21位。要使用8位整數表示這些標量值,通常需要多個UTF-8代碼單元。

let flowers = "Flowers ??"
for v in flowers.utf8 {
    print(v,"",separator: " ", terminator: "")//替換換行符
}
//!< 控制臺最終輸出:70 108 111 119 101 114 115 32 240 159 146 144
/*一個??的字符是unicode標量:\u{1F490}
flowermoji.unicodeScalars :32位的0001F490 表示字符為\u{1F490} 打印值為:128144
*/
let flowermoji = "??" 
let flowermojiUnicodeScalars = flowermoji.unicodeScalars //!< log:"\u{0001F490}" 這個是封包了
for v in flowermojiUnicodeScalars {
    print(v,v.value)//!< v.value = 128144  9*16 + 4*256 +15 * 256 *16 + 256 *256 = 128144
}
//將??unicode標量:\u{128144},轉為UTF-8編碼集合,會發現需要多個
var count = 0
var value = ""
for v in flowermoji.utf8 {
    count += 1
    value += "\(v) "
}
//!console.log:??unicode標量轉換成了4個utf8碼元集合分別是:240 159 146 144
print("\u{1F490}unicode標量轉換成了\(count)個utf8碼元集合分別是:\(value)")

比如let dogString = "Dog???"轉換UTF-8集合"68 111 103 226 128 188 240 159 144 182 "

dogString轉換UTF-8集合

2.UTF-16表示:
通過迭代字符串的utf16屬性來訪問字符串的UTF-16編碼格式的表示形式。utf16屬性的類型為String.UTF16View,與String.UTF8View同理。區別:String.UTF16View是無符號的16位整數UInt16值的集合 。字符串中Unicode標量值最長可達21位。要使用16位整數表示這些標量值,可能需要兩個UTF-16代碼單元。

let dogString = "Dog???"
var count = 0
var value = ""
for v in dogString.utf16 {
    count += 1
    value += "\(v) "
}
//控制臺輸出: ?? unicode標量轉換成了6個utf16碼元集合分別是:68 111 103 8252 55357 56374
print("\u{1F436}unicode標量轉換成了\(count)個utf16碼元集合分別是:\(value)")// ?? :\u{1F436}
dogString轉換UTF-16集合

3.Unicode Scalar 表示:
通過迭代字符串的unicodeScalars屬性來訪問字符串的Unicode標量表示形式(集合)。unicodeScalars屬性的類型為String.UnicodeScalarView。每個UnicodeScalar都有一個value屬性: Unicode.Scalar的實例對象,會使用無符號的32位整數UInt32,返回標量的值。

for scalar in dogString.unicodeScalars {
    print("\(scalar.value) ", terminator: "")// log "68 111 103 8252 128054 "
}
dogString轉換Unicode標量的集合

參考資料:
swift 5.1官方編程指南


推薦文章:
用Flutter 寫一個簡單頁面
5分鐘,帶你迅速上手Markdown語法
Swift 5.1 (2) - 運算符
Swift 5.1(1) - 基礎
iOS UI狀態保存和恢復(三)
iOS UI狀態保存和恢復(二)
iOS UI狀態保存和恢復(一)
iOS 中精確定時的常用方法
Sign In With Apple(一)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容