????一個(gè)字符串就是一組字符,比如"hello, world"或者"albatross"孩等。Swift中的字符串有String類型體現(xiàn)出來,一個(gè)字符串可以通過多種不同的方式來獲取不同的內(nèi)容采够,包括以一個(gè)字符的集合的方式肄方。
? ? Swift中的String和Character類型可以快速的處理代碼中的文本,且兼容Unicode,創(chuàng)建和操作字符串的語法很輕量和易讀蹬癌,string的字面量和C語言很像。字符串的連接很簡單隅要,使用加法運(yùn)算符(+)連接字符串就可以董济。字符串是否可變?nèi)Q于它是一個(gè)常量還是一個(gè)變量。你可以把常量,變量,字面量或者表達(dá)式插入到一個(gè)長字符串中欢搜,這個(gè)過程叫做字符串插入谴轮。這也就使字符串的展示,存儲(chǔ)和打印更加簡單书聚。
? ? 盡管Swift中的String的語法很簡單雌续,但是它有快速和現(xiàn)代的實(shí)現(xiàn)胯杭。每一個(gè)字符串都是有一組無關(guān)編碼的Unicode字符組成搏屑,并且可以訪問這個(gè)字符在不同Unicode形式下的值侣背。
NOTE:Swift的字符串和Foundation庫中的NSString可以橋接曲梗。Fondation庫同時(shí)擴(kuò)展了String,以暴露出NSString的方法菱蔬。所以Stirng類型的變量不需要轉(zhuǎn)換就可以訪問NSString的方法糯景。
字符串字面量
? ? 你可以在代碼中包含預(yù)定義的String的值,也就是字面量省骂。一個(gè)字符串的字面量是一組有雙括號(hào)包圍的字符。
? ? 可以使用字符串字面量初始化一個(gè)常量或者變量:
? ??????let someString = "Some string literal value
? ? 這里常量someString被推斷是String類型怠惶,因?yàn)樗褂昧俗址置媪砍跏蓟?b>
多行字符串字面量
需要你需要一個(gè)字符串跨越很多行轧粟,使用多行字符串字面量,一組由三個(gè)雙引號(hào)包圍的字符:
? ??????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."
????????""
????一個(gè)多行字符串字面量包含了三括號(hào)包含了的所有的行逃延。這個(gè)字符串從第一行的三個(gè)雙括號(hào)開始揽祥,在最后一行的三個(gè)雙括號(hào)結(jié)束。這就意味著,下面的2個(gè)字符串都既不是由換行符開始也不是由換行符結(jié)束:
? ??????let singleLineString = "These are the same."
????????let multilineString = """
????????These are the same.
????????""
? ? 在你的代碼中拄丰,一個(gè)多行字符串字面量包含了換行符俐末,那么字符串的值中也就有了換行符卓箫。如果你添加換行符只是為了增加可讀性垄潮,而不需要換行符在值中存在,那么在這一寫行末尾添加反斜杠\:
? ??????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."
????????""
? ? 如果要?jiǎng)?chuàng)建一個(gè)以換行符開頭或者結(jié)尾的多行字符串字面量旅急,在第一行或者最后一行寫一個(gè)空白行牡整。比如:
? ??????let lineBreaks = """
? ??????????????
????????This string starts with a line break.
????????It also ends with a line break.
????????""
? ? 多行字符串可以通過縮進(jìn)匹配代碼,終止符三個(gè)雙引號(hào)之前的空格符逃贝,會(huì)告訴Swift其它行前面需要忽略的空格符的數(shù)量。當(dāng)然在終止符三個(gè)雙引號(hào)前泥从,你在一行的開頭添加了空格符沪摄,那么這些空格符是不會(huì)被忽略的。
? ? 上面的例子中和敬,即使整個(gè)多行字符串都是被鎖進(jìn)的戏阅,但是第一行和最后一行都不是以空格為首的,中間的一行比終止引號(hào)那一行有更多的縮進(jìn)舱痘,因此它是以4個(gè)額外的空格符為首的离赫。
字符串字面量中的特殊字符
????字符串字面量可以包含以下特殊字符:
? ? 特殊的轉(zhuǎn)移字符: \0(空字符) ,\\ (反斜杠)旬盯,\t(tab),\n(換行符)胖翰,\r(會(huì)車符), \"(雙引號(hào)), \'(單引號(hào))
? ? Unicode標(biāo)量:寫成\u{n},其中n是一個(gè)1-8位的16進(jìn)制的數(shù)字懊缺,這個(gè)數(shù)字等于一個(gè)Unicode代碼單元培他。
? ? 下面的4個(gè)例子展示了這種特殊的字符。常量wiseWords包含了2個(gè)轉(zhuǎn)義后的雙引號(hào)怔毛,常量dollarSign腾降,blackHeart和sparklingHeart展示了Unicode標(biāo)量的格式:
? ??????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
? ? 在多行字符串字面量中碎绎,使用了3個(gè)雙括號(hào)而不是一個(gè)雙括號(hào),所以不需要轉(zhuǎn)義也可以包含雙引號(hào)奸晴。如果要在多行字符串字面量包含三個(gè)雙引號(hào)日麸,那么請至少轉(zhuǎn)義其中的一個(gè)引號(hào),例如:
? ??????let threeDoubleQuotes = """
????????Escaping the first quote \"""
????????Escaping all three quotes \"\"\"
????????""
初始化空字符串
? ? 有時(shí)為了包含一個(gè)長字符串,我們需要先創(chuàng)建一個(gè)空字符串墩划,這個(gè)時(shí)候我們可以把空的字符串字面量賦值給變量嗡综,或者使用初始化的語法初始化一個(gè)新的字符串實(shí)例:
? ??????var emptyString = "" // empty string literal
????????var anotherEmptyString = String()? // initializer syntax
????????// 2個(gè)字符串都是空字符串,彼此相等
? ? 通過檢查他的isEmpty屬性可以知道String值是不是一個(gè)空字符串:
? ??????if emptyString.isEmpty {
????????? ? print("Nothing to see here")
????????}
????????// 打印 "Nothing to see here”
可變字符串
? ? 一個(gè)字符串值賦值給一個(gè)變量,這個(gè)字符串就可以變修改,賦值給常量,這個(gè)字符串就不允許被修改:
? ??????var variableString = "Horse"
????????variableString += " and carriage"
????????// variableString is now "Horse and carriage"
????????let constantString = "Highlander"
????????constantString += " and another Highlander"
????????// 編譯時(shí)錯(cuò)誤 -"a constant string cannot be modified"
NOTE:這個(gè)中方式和OC中選擇不同的實(shí)現(xiàn)類來表明是否可變不一樣
字符串是一個(gè)值類型
? ? Swift中的值變量是一個(gè)值類型察净。如果你創(chuàng)建了一個(gè)新的String值盼樟,當(dāng)你把它傳給一個(gè)函數(shù)或者方法的時(shí)候,他的值將會(huì)被拷貝。所有情況下译秦,根據(jù)一個(gè)已經(jīng)存在的String創(chuàng)建了一個(gè)新的copy,這個(gè)新的拷貝被傳遞且擁有自己的內(nèi)存空間,和模版不再是同一個(gè)變量棋返。
? ? Swift中String默認(rèn)拷貝的行為雷猪,讓你在一個(gè)函數(shù)或者方法中的得到一個(gè)String類型的入?yún)r(shí),可以確定你擁有一個(gè)明確的String的值求摇,不需要關(guān)心它的來出。你可以肯定,這個(gè)字符串不會(huì)被其他地方改變,除非你自己去改變它验夯。
? ? 在背后摔刁,Swift的編譯器會(huì)優(yōu)化Strng的使用,因此绑谣,真正的拷貝行為只有在確實(shí)需要的時(shí)候才會(huì)發(fā)生拗引。這讓你在使用String的時(shí)候總是可以獲得很不錯(cuò)的性能。 ? ?