字符串
1 什么是字符串?
Go 语言中的字符串是一个字节切片。把内容放在双引号””之间,我们可以创建一个字符串。让我们来看一个创建并打印字符串的简单示例。
package main
import (
"fmt"
)
func main() {
name := "Hello World"
fmt.Println(name)
}
上面的程序将会输出 Hello World
。
Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。
2 获取字符串中的某个元素
字符串底层就是一个byte数组,它的使用方法和数组相同,并且可以和 []byte 类型相互转换。
package main
import "fmt"
func main() {
var str = "hello"
fmt.Printf("str[0]=%c length(str)=%d\n", str[0], len(str))
}
程序第7行,取字符串第0个位置的值,用法和数组相同。字符串是由byte字节组成,所以字符串的长度是byte字节的长度,一个英文字符占1个byte,因此src字符串长度为5个byte。上面的程序输出为:
str[0]=h length(str)=5
3 遍历字符串
由于字符串是一个字节切片,所以我们可以获取字符串的每一个字节。
package main
import (
"fmt"
)
func testString(str string) {
for index, val := range str {
fmt.Printf("str[%d]=%d\n", index, val)
//fmt.Printf("str[%d]=%c\n", index, val)
}
}
func main() {
name := "hello"
testString(name)
}
我们用了一个 for 循环以打印这些字节。%d
格式限定符用于指定 ascii 码。这些打印出来的字符是 “hello”字符对应的ascii码数字。上面的程序输出:
str[0]=104
str[1]=101
str[2]=108
str[3]=108
str[4]=111
%c
格式限定符用于打印字符串的字符。这个程序输出结果是:
str[0]=h
str[1]=e
str[2]=l
str[3]=l
str[4]=o
4 字符串和[]byte类型相互转换
4.1 字符串转成byte类型的切片
package main
import "fmt"
func main() {
str := "hello"
byteSlice := []byte(str)
fmt.Printf("%c", byteSlice)
}
上面的程序输出为:[h e l l o]
4.2 byte类型切片转为字符串
package main
import "fmt"
func main() {
byteSlice := []byte{'h', 'e', 'l', 'l', 'o'}
str := string(byteSlice)
fmt.Println(str)
}
[]byte类型,元素是字符,单引号包裹。上面的程序输出为:hello
5 rune
rune 是 Go 语言的内建类型,它也是 int32 的别称。Go 中的字符串是兼容 Unicode 编码的,并且使用 UTF-8 进行编码。rune类型用来表示utf8字符,一个rune字符由1个或多个byte组成。在 Go 语言中,rune 表示一个代码点。代码点无论占用多少个字节,都可以用一个 rune 字符来表示。
5.1 定义rune并赋值
package main
import "fmt"
func main() {
var b rune
//b = 'hello' 单引号包裹的是字符,放入字符串报错
//b = 'h' 可以赋值英文字符,utf-8中占1个字节
b = '中' //可以赋值中文字符,utf-8中占3个字节
fmt.Printf("%c", b)
}
上面程序输出为:中
rune类型切片与 byte类型切片的比较如下:byte是一个字节,因此中文字符放不进去,而rune可以放任意字符。
5.1 字符串转成rune类型的切片
package main
import "fmt"
func main() {
str := "中国人民nb"
runeSlice := []rune(str)
fmt.Printf("%c", runeSlice)
}
上面程序输出为:[中 国 人 民 n b]
5.2 rune类型切片转为字符串
package main
import "fmt"
func main() {
runeSlice := []rune{'中', '国', '人', '民', 'n','b'}
str := string(runeSlice)
fmt.Println(str)
}
上面程序输出为:中国人民nb
6 字符串的长度
[utf8 package] 包中的 func RuneCountInString(s string) (n int)
方法用来获取字符串的长度。这个方法传入一个字符串参数然后返回字符串中的 rune 的数量。
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
str := "中国"
fmt.Printf("length of %s is %d\n", str, utf8.RuneCountInString(str))
fmt.Printf("length of %s is %d", str, len(str))
}
RuneCountInString
方法统计长度,返回的是字符rune字符长度,len
方法统计长度,返回的是字节byte长度
上面程序输出为:
length of 中国 is 2
length of 中国 is 6
7 字符串是不可变的
Go 中的字符串是不可变的。一旦一个字符串被创建,那么它将无法被修改。
package main
import (
"fmt"
)
func mutate(s string)string {
s[0] = 'a' //any valid unicode character within single quote is a rune
return s
}
func main() {
h := "hello"
fmt.Println(mutate(h))
}
在上面程序中的第 8 行,我们试图把这个字符串中的第一个字符修改为 ‘a’。由于字符串是不可变的,因此这个操作是非法的。所以程序抛出了一个错误 main.go:8: cannot assign to s[0]。
为了修改字符串,可以把字符串转化为一个 rune 切片或者byte切片。然后对这个切片可以进行任何想要的改变,最后再转化为一个字符串。
package main
import (
"fmt"
)
func mutate(s []rune) string {
s[0] = 'a'
return string(s)
}
func main() {
h := "hello"
fmt.Println(mutate([]rune(h)))
}
在上面程序的第 7 行,mutate
函数接收一个 rune 切片参数,它将切片的第一个元素修改为 'a'
,然后将 rune 切片转化为字符串,并返回该字符串。程序的第 13 行调用了该函数。我们把 h
转化为一个 rune 切片,并传递给了 mutate
。这个程序输出 aello
。