Go 语言中可以使用反引号或者双引号来定义字符串。反引号表示原生的字符串,即不进行转义。
- 双引号:字符串使用双引号括起来,其中的相关的转义字符将被替换。例如:
-
str := "Hello World! \n Hello Gopher! \n" 输出: Hello World! Hello Gopher!
-
- 反引号:字符串使用反引号括起来,其中的相关的转义字符不会被替换。例如:
-
str := `Hello World! \n Hello Gopher! \n` 输出: Hello World! \nHello Gopher! \n
-
双引号中的转义字符被替换,而反引号中原生字符串中的 \n
会被原样输出。
Go 语言中的string类型是一种值类型,存储的字符串是不可变的,如果要修改string内容需要将string转换为[]byte或[]rune,并且修改后的string内容是重新分配的。那么byte和rune的区别是什么(下面写法是type别名):
type byte = uint8
type rune = int32
从上面的定义中我们可清楚看到两者的区别。而string类型的零值是为长度为零的字符串,即空字符串 ""。
一般的比较运算符(==、!=、=、>)通过在内存中按字节比较来实现字符串的对比。你可以通过函数 len() 来获取字符串所占的字节长度,例如:len(str)。
字符串的内容(纯字节)可以通过标准索引法来获取,在中括号 [] 内写入索引,索引从 0 开始计数:字符串 str 的第 1 个字节:str[0] 第 i 个字节:str[i - 1] 最后 1 个字节:str[len(str)-1]
需要注意的是,在Go语言代码使用 UTF-8 编码,同时标识符也支持 Unicode 字符。在标准库 unicode 包中,提供了对 Unicode 相关编码、解码的支持。而UTF8编码由Go语言之父Ken Thompson和Rob Pike共同发明的,现在已经是Unicode的标准。
Go语言默认使用UTF-8编码,对Unicode的支持非常好。但这也带来一个问题,也就是很多资料中提到的“获取字符串长度”的问题。内置的len()函数获取的是每个字符的UTF-8编码的长度和,而不是直接的字符数量。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "其实就是rune"
fmt.Println(len(s)) // "16"
fmt.Println(utf8.RuneCountInString(s)) // "8"
}
如字符串含有中文等字符,我们可以看到每个中文字符的索引值相差3。下面代码同时说明了在for range循环处理字符时,不是按照字节的方式来处理的。v其实际上是一个rune类型值。实际上,Go语言的range循环在处理字符串的时候,会自动隐式解码UTF8字符串。
package main
import (
"fmt"
)
func main() {
s := "Go语言四十二章经"
for k, v := range s {
fmt.Printf("k:%d,v:%c == %d\n", k, v, v)
}
}
程序输出:
k:0,v:G == 71
k:1,v:o == 111
k:2,v:语 == 35821
k:5,v:言 == 35328
k:8,v:四 == 22235
k:11,v:十 == 21313
k:14,v:二 == 20108
k:17,v:章 == 31456
k:20,v:经 == 32463
注意事项:
获取字符串中某个字节的地址的行为是非法的,例如:&str[i]。