4.6 字符串

字符串是 UTF-8 字符的一個序列(當字符爲 ASCII 碼時則佔用 1 個字節,其它字符根據需要佔用 2-4 個字節)。UTF-8 是被廣泛使用的編碼格式,是文本文件的標準編碼,其它包括 XML 和 JSON 在內,也都使用該編碼。由於該編碼對佔用字節長度的不定性,Go 中的字符串也可能根據需要佔用 1 至 4 個字節(示例見第 4.6 節),這與其它語言如 C++、Java 或者 Python 不同(Java 始終使用 2 個字節)。Go 這樣做的好處是不僅減少了內存和硬盤空間佔用,同時也不用像其它語言那樣需要對使用 UTF-8 字符集的文本進行編碼和解碼。

字符串是一種值類型,且值不可變,即創建某個文本後你無法再次修改這個文本的內容;更深入地講,字符串是字節的定長數組。

Go 支持以下 2 種形式的字面值:

  • 解釋字符串:

    該類字符串使用雙引號括起來,其中的相關的轉義字符將被替換,這些轉義字符包括:

    • \n:換行符
    • \r:回車符
    • \t:tab 鍵
    • \u\U:Unicode 字符
    • \\:反斜槓自身
  • 非解釋字符串:

    該類字符串使用反引號括起來,支持換行,例如:

      `This is a raw string \n` 中的 `\n\` 會被原樣輸出。
    

和 C/C++不一樣,Go 中的字符串是根據長度限定,而非特殊字符\0

string 類型的零值爲長度爲零的字符串,即空字符串 ""

一般的比較運算符(==!=<<=>=>)通過在內存中按字節比較來實現字符串的對比。你可以通過函數 len() 來獲取字符串所佔的字節長度,例如:len(str)

字符串的內容(純字節)可以通過標準索引法來獲取,在中括號 [] 內寫入索引,索引從 0 開始計數:

  • 字符串 str 的第 1 個字節:str[0]
  • 第 i 個字節:str[i - 1]
  • 最後 1 個字節:str[len(str)-1]

需要注意的是,這種轉換方案只對純 ASCII 碼的字符串有效。

注意事項 獲取字符串中某個字節的地址的行爲是非法的,例如:&str[i]

字符串拼接符 +

兩個字符串 s1s2 可以通過 s := s1 + s2 拼接在一起。

s2 追加在 s1 尾部並生成一個新的字符串 s

你可以通過以下方式來對代碼中多行的字符串進行拼接:

str := "Beginning of the string " +
    "second part of the string"

由於編譯器行尾自動補全分號的緣故,加號 + 必須放在第一行。

拼接的簡寫形式 += 也可以用於字符串:

s := "hel" + "lo,"
s += "world!"
fmt.Println(s) //輸出 “hello, world!”

在循環中使用加號 + 拼接字符串並不是最高效的做法,更好的辦法是使用函數 strings.Join()(第 4.7.10 節),有沒有更好地辦法了?有!使用字節緩衝(bytes.Buffer)拼接更加給力(第 7.2.6 節)!

在第 7 章,我們會講到通過將字符串看作是字節(byte)的切片(slice)來實現對其標準索引法的操作。會在第 5.4.1 節中講到的 for 循環只會根據索引返回字符串中的純字節,而在第 5.4.4 節(以及第 7.6.1 節的示例)將會展示如何使用 for-range 循環來實現對 Unicode 字符串的迭代操作。在下一節,我們會學習到許多有關字符串操作的函數和方法,同時 fmt 包中的 fmt.Sprint(x) 也可以格式化生成並返回你所需要的字符串(第 4.4.3 節)。

練習 4.6 count_characters.go

創建一個用於統計字節和字符(rune)的程序,並對字符串 asSASA ddd dsjkdsjs dk 進行分析,然後再分析 asSASA ddd dsjkdsjsこん dk,最後解釋兩者不同的原因(提示:使用 unicode/utf8 包)。

鏈接

results matching ""

    No results matching ""