【Go 简明手册】Go基本语法——字符串
Go 语言中的字符串是 UTF-8 字符的一个序列(当字符为 ASCII 码时则占用 1 个字节,其它字符根据需要占用 2-4 个字节)。UTF-8 是被广泛使用的编码格式,是文本文件的标准编码,其它包括 XML 和 JSON 在内,也都使用该编码。由于该编码对占用字节长度的不定性,Go 中的字符串也可能根据需要占用 1 至 4 个字节,这与其它语言如 C++、Java 或者 Python 不同。Go 这样做的好处是不仅减少了内存和硬盘空间占用,同时也不用像其它语言那样需要对使用 UTF-8 字符集的文本进行编码和解码。
Go 语言中字符串的可以使用双引号 (") 或者反引号 (`) 来创建。双引号用来创建可解析的字符串字面量,所谓可解析的是指字符串中的一些符号可以被格式化为其他内容,如 \n 在在输出时候会被格式化成换行符,如果需要按照原始字符输出必须进行转义。而反引号创建的字符串原始是什么样,那输出还是什么,不需要进行任何转义。以下是几个例子:
1 |
|
Go 语言中的部分转义字符如下表所示:
转义字符 | 含义 |
---|---|
\\ |
表示反斜线 |
\' |
单引号 |
\" |
双引号 |
\n |
换行符 |
\uhhhh |
4 个 16 进制数字给定的 Unicode 字符 |
在 Go 语言中单个字符可以使用单引号 (') 来创建。之前的课程中,我们有学习过 rune 类型,它等同于 int32,在 Go 语言中,一个单一的字符可以用一个单一的 rune 来表示。这也是容易理解的,因为 Go 语言的字符串是 UTF-8 编码,其底层使用 4 个字节表示,也就是 32 bit。
在 Go 语言中,字符串支持切片操作,但是需要注意的是如果字符串都是由 ASCII 字符组成,那可以随便使用切片进行操作,但是如果字符串中包含其他非 ASCII 字符,直接使用切片获取想要的单个字符时需要十分小心,因为对字符串直接使用切片时是通过字节进行索引的,但是非 ASCII 字符在内存中可能不是由一个字节组成。如果想对字符串中字符依次访问,可以使用 range 操作符。另外获取字符串的长度可能有两种含义,一种是指获取字符串的字节长度,一种是指获取字符串的字符数量。字符串支持以下操作:
语法 | 描述 |
---|---|
s += t |
将字符串 t 追加到 s 末尾 |
s + t |
将字符串 s 和 t 级联 |
s[n] |
从字符串 s 中索引位置为 n 处的原始字节 |
s[n:m] |
从位置 n 到位置 m-1 处取得的字符(字节)串 |
s[n:] |
从位置 n 到位置 len(s)-1 处取得的字符(字节)串 |
s[:m] |
从位置 0 到位置 m-1 处取得的字符(字节)串 |
len(s) |
字符串 s 中的字节数 |
len([]rune(s)) |
字符串 s 中字符的个数,可以使用更快的方法 utf8.RuneCountInString() |
[]rune(s) |
将字符串 s 转换为一个 unicode 值组成的串 |
string(chars) |
chars 类型是 []rune 或者 []int32 , 将之转换为字符串 |
[]byte(s) |
无副本的将字符串 s 转换为一个原始的字节的切片数组,不保证转换的字节是合法的 UTF-8 编码字节 |
让我们尝试一个例子,创建源文件 string_t.go,然后输入以下源代码:
1 |
|
然后通过以下方式运行,在这里一起显示了程序的输出:
1 |
|
说明:
通过前面的课程我们知道通过 \uhhhh 的方式我们可以通过创建 Unicode 字符。
在以上程序中,首先通过 := 符号创建了变量 t0,其值为 \u6B22\u8FCE\u6765\u5230,是 欢迎来到 中文字符的 unicode 编码,然后以同样的方式创建了变量 t1,其值为 实验楼,然后通过 + 操作符将 t0 和t1 拼接赋值给 t2。然后我们通过 range 操作符号对 unicode 字符串 t2 中的每一个 unicode 字符依次操作,我们这里只是简单的打印出每个字符在 t2 中的位置,每个字符的 unicode 码值,每个字符的字面量,每个字符的十六进制值,以及每个字符的字节长度。
这里我们使用 fmt 包种支持的格式指令,如果读者学习过 C 语言的话就一目了然。接着,我们通过 len 操作符计算出了每个字符串的字节长度。最后,我们使用切片访问了字符串 t2 的第 0-1 个字节,也就是前两个字节,其内容为 E6AC。前面我们说到不能使用切片的方式访问非 ASCII 字符串中的字符,原因在这里一目了然。字符 欢 其底层使用了三个字节表示,内容是 E6ACA2,如果只是简单的使用切片(只取切片中的一项)访问的是不能访问到整个字符的,因为字符的切片是通过字节数来索引的。