Swift的字符串類型與Foundation的NSString類連接。Foundation還擴展了字符串來公開由NSString定義的方法。這意味著,如果您導(dǎo)入Foundation,您可以在字符串中訪問這些NSString方法,而不需要進(jìn)行強制轉(zhuǎn)換。
單行字符串
let someString = "Some stirng"
多行文本
多行文本使用 """ 內(nèi)容 """ 沒錯,就是三個引號開頭,三個引號結(jié)尾。
多行字符串文字包含了它的起始引號和結(jié)束引號之間的所有行
let lyric = """那是你的眼神,明亮又美麗啊啊啊~~~"""print(lyric) 結(jié)果:那是你的眼神,明亮又美麗啊啊啊~~~
好吧,這個我一開始以為只是在格式上可以寫成多行,沒想到結(jié)果就是多行,效果等同于\n,而且這樣寫法更加方便。
還有就是當(dāng)我們想在多行文本中想控制某行不換行,可以選擇在某行的末尾寫上 \ 那么下一行就不會換行了
let lyric = """那是你的眼神,明亮又美麗\啊啊啊~~~""" 結(jié)果:那是你的眼神,明亮又美麗啊啊啊~~~
在多行文本中,我們可以在結(jié)束引號的前面設(shè)定空格,來限定整段文本的縮進(jìn):
let lyric = """ 那是你的眼神,明亮又美麗 啊啊啊~~~ """
上面例子中,我們在最后"""前設(shè)定了2個空格,那么之前的文本必須都是縮進(jìn)2個空格如果你這樣寫:
let lyric = """那是你的眼神,明亮又美麗啊啊啊~~~ """
你會發(fā)現(xiàn)會報錯Insufficient indentation of line in multi-line string literal 多行字符串文字的行縮不足
字符串中特殊字符
(反斜杠)
let test = "====\\===="結(jié)果:====\====
\t(水平選項卡)
let test = "\t1\t2\t3"結(jié)果: 1 2 3
\n(換行符)
let test = "\n1\n2\n3"結(jié)果: 123
\r(回車)
let test = "\r1\r2\r3"結(jié)果: 123
從結(jié)果來看,\r和\n似乎沒有區(qū)別,但既然存在即表示肯定是有區(qū)別的
'\r'是回車,\r 使光標(biāo)到行首. '\n'是換行,\n 使光標(biāo)下移一格,通常敲一個回車鍵,即是回車,又是換行(\r\n)。Unix中每行結(jié)尾只有“<換行>”,即“\n”;Windows中每行結(jié)尾是“<換行><回車>”,即“\n\r”;Mac中每行結(jié)尾是“<回車>”
一般遇到的情況是在解析Json字符串,網(wǎng)頁數(shù)據(jù),文件信息的時候會出現(xiàn)不同的應(yīng)對.
"(雙引號)
let test = "\"認(rèn)識自己的無知是認(rèn)識世界的最可靠的方法?!峨S筆集》\""結(jié)果:"認(rèn)識自己的無知是認(rèn)識世界的最可靠的方法。——《隨筆集》"
'(單引號)
let test = "\'曦\'"結(jié)果:'曦'
Unicode 字符就直接采用官網(wǎng)的了
let dollarSign = "\u{24}" // $, Unicode scalar U+0024let blackHeart = "\u{2665}" // ?, Unicode scalar U+2665let sparklingHeart = "\u{1F496}" // ??, Unicode scalar U+1F496 結(jié)果:$ ? ??
空字符串
我們來看一下如果定義一個空字符串:
var emptyString = ""或者var emptyString = String()
判斷字符串是否為空:
isEmpty 方法
var emptyString = "" if emptyString.isEmpty { print("emptyStirng is empty")}
字符串可變性
var variableString = "Horse"variableString += " and carriage" 結(jié)果:variableStrin:Horse and carriage
let constantString = "Highlander"constantString += " and another Highlander"發(fā)生錯誤。Left side of mutating operator isn't mutable: 'constantString' is a 'let' constant變異操作符的左側(cè)是不可改變的:“常量字符串”是一個“l(fā)et”常量
簡單來說就是variableString 是變量,可以通過+操作符來追加字符串, constantString 為常量,不可修改。
這個我不得不吐槽一下,官網(wǎng)的這個解釋,不就是常量不可修改嘛,說什么可變性。
字符串是值類型
If you create a new String value, that String value is copied when it’s passed to a function or method, or when it’s assigned to a constant or variable. In each case, a new copy of the existing String value is created, and the new copy is passed or assigned, not the original version.
如果您創(chuàng)建一個新的字符串值,那么當(dāng)它傳遞給一個函數(shù)或方法時,或者當(dāng)它被分配給一個常量或變量時,該字符串值將被復(fù)制。
在不同情況下,都會創(chuàng)建一個現(xiàn)有字符串值的新副本,并分配新副本,而不是原始版本。
Swift’s copy-by-default String behavior ensures that when a function or method passes you a String value, it’s clear that you own that exact String value, regardless of where it came from. You can be confident that the string you are passed won’t be modified unless you modify it yourself.
Swift的 copy-by-default 行為可以確保當(dāng)函數(shù)或方法傳遞給你一個字符串值時,不管它是從哪里來的,你都能清楚地知道你的值是什么。您可以確信,您所傳遞的字符串不會被修改,除非您自己修改它。
Behind the scenes, Swift’s compiler optimizes string usage so that actual copying takes place only when absolutely necessary. This means you always get great performance when working with strings as value types.
在后臺,Swift的編譯器優(yōu)化了字符串的使用,所以只有在絕對必要的情況下才會進(jìn)行實際的復(fù)制。這意味著在使用字符串作為值類型時,您總是獲得很好的性能。
這個就有別于OC了,OC中有明確的分為NSString(不可變)和NSMutableString(可變),swift中只有這么一種了,通過對此的優(yōu)化更加確保了數(shù)據(jù)的安全。
字符
定義一個字符(Character)類型的常量charA
let charA:Character = "A"print("charA:\(charA)")結(jié)果:charA:A
您可以通過使用for循環(huán)遍歷字符串來訪問字符串的單個字符值:
let character = ""let str = "窗外的麻雀"for character in str { print(character)}結(jié)果:窗外的麻雀
創(chuàng)建一個字符值數(shù)組:
let catCharacters: [Character] = ["C", "a", "t", "!", "??"]print(catCharacters)結(jié)果:["C", "a", "t", "!", "??"]
可以通過String(字符數(shù)組)來將字符數(shù)組轉(zhuǎn)換成字符串
let catCharacters: [Character] = ["C", "a", "t", "!", "??"]let catString = String(catCharacters)print(catString)結(jié)果:Cat!??
字符串的連接:
我們可以用 + 操作符連接字符串
let string1 = "hello"let string2 = " there"var welcome = string1 + string2print("welcome \(welcome)")結(jié)果:welcome hello there
除了+操作符之外,還有append方法
let string1 = "hello"let string2 = " there"var welcome = string1 + string2 let exclamationMark: Character = "!"welcome.append(exclamationMark)print("welcome \(welcome)")結(jié)果:welcome hello there!
append是將字符串追加到原本字符串的末尾
以上的添加方法是通過連接兩個字符串的值形成一個新的值
而在有的時候我們其實只需要臨時的展示而已,不需要去改變原有的值,那么這個時候其實只需要這樣做就可以了:
let badStart = """onetwo"""let end = """three"""print(badStart + end)print(badStart) 結(jié)果:onetwothree onetwo
可以看到我們在輸出print中將其相加,雖然顯示了,但其實badStart的結(jié)果并沒有改變。
字符串的插值
在使用字符串的時候,我們可能需要利用其它的變量來改變我們目前的數(shù)據(jù),而這個時候我們可以使用 \(value) 來將我們需要的值
let multiplier = 3let message = "\(multiplier) times 2.5 is \(Double(multiplier) * 2.5)" 結(jié)果:3 times 2.5 is 7.5
當(dāng)然了,這個也不是萬能,它是不能將未轉(zhuǎn)義的\直接放置于()中的:
錯誤的方式
let message = "\(\)"print(message) let message = "\(\')"print(message)
正確的方式是這樣的:
let message = "\("\'")"print(message)結(jié)果:'
計算字符的個數(shù)
計算字符的個數(shù)是我們比較常用的方法count
let unusualMenagerie = "Koala ??, Snail ??, Penguin ??, Dromedary ??"print("unusualMenagerie has \(unusualMenagerie.count) characters")結(jié)果:unusualMenagerie has 40 characters
當(dāng)然了,count并不總是能夠計算清楚我們的字符個數(shù):
var word = "cafe"print("the number of characters in \(word) is \(word.count)")這個計算結(jié)果是4word += "\u{301}" print("the number of characters in \(word) is \(word.count)")當(dāng)我們計算的會發(fā)現(xiàn)結(jié)果仍然是4
這是為什么呢?
因為swift中的字符串運用了擴展字元簇(Extended Grapheme Clusters)
擴展字元簇可以由多個Unicode標(biāo)量組成。
這意味著不同的字符和相同字符的不同表示可以要求不同的內(nèi)存數(shù)量來存儲。
因此,Swift中的字符不會在字符串的表示中占用相同數(shù)量的內(nèi)存。
結(jié)果,字符串中的字符數(shù)無法計算.
如果您使用的是特別長的字符串值,請注意,count屬性必須遍歷整個字符串中的Unicode標(biāo)量,以便確定該字符串的字符。
比如:字母é可以是一個單獨的Unicode scalar:U+00E9,也可以是多個純量的組合:U+0065U+0301 (其中U+0065就是字母e)。在Swift中,這兩種情況都認(rèn)為是一個字符,因此獲取字符串長度的時候(用全局函數(shù)count()),返回的值是相同的,這意味著字符串的改變并不一定意味著其長度發(fā)生變化。
count屬性返回的字符數(shù)并不總是與包含相同字符的NSString的長度屬性相同。
NSString的length是基于字符串的utf-16表示的16位代碼單元的數(shù)量,而不是字符串中Unicode擴展的grapheme集群的數(shù)量
字符串索引
let greeting = "Guten Tag!"http://字符串中的開頭字母print(greeting[greeting.startIndex])//index()表示獲取字符串中某個下標(biāo)的元素,before意味著獲取最后一位的之前的下標(biāo)//endIndex表示字符串最后一位print(greeting[greeting.index(before: greeting.endIndex)])//after表示獲取某個下標(biāo)之后print(greeting[greeting.index(after: greeting.startIndex)])//這個方法表示以startIndex下標(biāo)開始,偏移7位let index = greeting.index(greeting.startIndex, offsetBy: 7)print(greeting[index])結(jié)果:G!ua
使用索引屬性來訪問字符串中各個字符的所有索引:
for index in greeting.indices { print("\(greeting[index]) ", terminator: "")}結(jié)果:G u t e n T a g !
這里的terminator是print方法中參數(shù),默認(rèn)是添加換行符\n
let greeting = "Guten Tag!" for index in greeting.indices { print("\(greeting[index]) ", terminator: "\n")}G u t e n T a g !
感覺跟print沒有區(qū)別吧。
let greeting = "Guten Tag!" for index in greeting.indices { print("\(greeting[index]) ", terminator: "1")}結(jié)果:G 1u 1t 1e 1n 1 1T 1a 1g 1! 1
這個其實就是在每次獲取單個字符之后添加一個字符。
字符串的插入和刪除
插入
insert(value,at:index)
var welcome = "hello"welcome.insert("!", at:welcome.endIndex)print(welcome)結(jié)果:hello! var welcome = "hello!"welcome.insert(contentsOf: " world", at: welcome.index(before: welcome.endIndex))print(welcome)結(jié)果:hello world!
移除
remove(at:index)
根據(jù)下標(biāo)進(jìn)行移除
removeSubrange
根據(jù)提供的范圍進(jìn)行移除
var welcome = "hello!"welcome.remove(at: welcome.index(before: welcome.endIndex))print(welcome)結(jié)果:hello var welcome = "hello world"http://空格的位置 - 末尾let range = welcome.index(welcome.endIndex, offsetBy: -6)..<welcome.endIndexwelcome.removeSubrange(range)print(welcome)結(jié)果:hello
后續(xù)更新,敬請期待...
作者:如風(fēng)如花不如你
鏈接:http://www.itdecent.cn/p/87c29641db61
來源:簡書
簡書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請聯(lián)系作者獲得授權(quán)并注明出處。