字符串是 UTF-8 字符的一個(gè)序列(當(dāng)字符為 ASCII 碼時(shí)則占用 1 個(gè)字節(jié),其它字符根據(jù)需要占用 2-4 個(gè)字節(jié))。UTF-8 是被廣泛使用的編碼格式,是文本文件的標(biāo)準(zhǔn)編碼,其它包括 XML 和 JSON 在內(nèi),也都使用該編碼。由于該編碼對(duì)占用字節(jié)長(zhǎng)度的不定性,Go 中的字符串也可能根據(jù)需要占用 1 至 4 個(gè)字節(jié)(示例見(jiàn)第 4.6 節(jié)),這與其它語(yǔ)言如 C++、Java 或者 Python 不同(Java 始終使用 2 個(gè)字節(jié))。Go 這樣做的好處是不僅減少了內(nèi)存和硬盤空間占用,同時(shí)也不用像其它語(yǔ)言那樣需要對(duì)使用 UTF-8 字符集的文本進(jìn)行編碼和解碼。
字符串是一種值類型,且值不可變,即創(chuàng)建某個(gè)文本后你無(wú)法再次修改這個(gè)文本的內(nèi)容;更深入地講,字符串是字節(jié)的定長(zhǎng)數(shù)組。
Go 支持以下 2 種形式的字面值:
解釋字符串:
該類字符串使用雙引號(hào)括起來(lái),其中的相關(guān)的轉(zhuǎn)義字符將被替換,這些轉(zhuǎn)義字符包括:
\n
:換行符\r
:回車符\t
:tab 鍵\u
或 \U
:Unicode 字符\\
:反斜杠自身非解釋字符串:
該類字符串使用反引號(hào)括起來(lái),支持換行,例如:
`This is a raw string \n` 中的 `\n\` 會(huì)被原樣輸出。
和 C/C++不一樣,Go 中的字符串是根據(jù)長(zhǎng)度限定,而非特殊字符\0
。
string
類型的零值為長(zhǎng)度為零的字符串,即空字符串 ""
。
一般的比較運(yùn)算符(==
、!=
、<
、<=
、>=
、>
)通過(guò)在內(nèi)存中按字節(jié)比較來(lái)實(shí)現(xiàn)字符串的對(duì)比。你可以通過(guò)函數(shù) len()
來(lái)獲取字符串所占的字節(jié)長(zhǎng)度,例如:len(str)
。
字符串的內(nèi)容(純字節(jié))可以通過(guò)標(biāo)準(zhǔn)索引法來(lái)獲取,在中括號(hào) []
內(nèi)寫入索引,索引從 0 開始計(jì)數(shù):
str[0]
str[i - 1]
str[len(str)-1]
需要注意的是,這種轉(zhuǎn)換方案只對(duì)純 ASCII 碼的字符串有效。
注意事項(xiàng) 獲取字符串中某個(gè)字節(jié)的地址的行為是非法的,例如:&str[i]
。
字符串拼接符 +
兩個(gè)字符串 s1
和 s2
可以通過(guò) s := s1 + s2
拼接在一起。
s2
追加在 s1
尾部并生成一個(gè)新的字符串 s
。
你可以通過(guò)以下方式來(lái)對(duì)代碼中多行的字符串進(jìn)行拼接:
str := "Beginning of the string " +
"second part of the string"
由于編譯器行尾自動(dòng)補(bǔ)全分號(hào)的緣故,加號(hào) +
必須放在第一行。
拼接的簡(jiǎn)寫形式 +=
也可以用于字符串:
s := "hel" + "lo,"
s += "world!"
fmt.Println(s) //輸出 “hello, world!”
在循環(huán)中使用加號(hào) +
拼接字符串并不是最高效的做法,更好的辦法是使用函數(shù) strings.Join()
(第 4.7.10 節(jié)),有沒(méi)有更好地辦法了?有!使用字節(jié)緩沖(bytes.Buffer
)拼接更加給力(第 7.2.6 節(jié))!
在第 7 章,我們會(huì)講到通過(guò)將字符串看作是字節(jié)(byte)的切片(slice)來(lái)實(shí)現(xiàn)對(duì)其標(biāo)準(zhǔn)索引法的操作。會(huì)在第 5.4.1 節(jié)中講到的 for 循環(huán)只會(huì)根據(jù)索引返回字符串中的純字節(jié),而在第 5.4.4 節(jié)(以及第 7.6.1 節(jié)的示例)將會(huì)展示如何使用 for-range 循環(huán)來(lái)實(shí)現(xiàn)對(duì) Unicode 字符串的迭代操作。在下一節(jié),我們會(huì)學(xué)習(xí)到許多有關(guān)字符串操作的函數(shù)和方法,同時(shí) fmt
包中的 fmt.Sprint(x)
也可以格式化生成并返回你所需要的字符串(第 4.4.3 節(jié))。
練習(xí) 4.6 count_characters.go
創(chuàng)建一個(gè)用于統(tǒng)計(jì)字節(jié)和字符(rune)的程序,并對(duì)字符串 asSASA ddd dsjkdsjs dk
進(jìn)行分析,然后再分析 asSASA ddd dsjkdsjsこん dk
,最后解釋兩者不同的原因(提示:使用 unicode/utf8
包)。