字符串
Go语言默认使用UTF-8编码来处理Unicode。每个中文字符在UTF-8中占3个字节。
简单理解:
- Unicode字符集:每个字符对应一个十六进制的数字(类似一个字典表)。
- UTF-8:是一套编码规则,将Unicode字符集中字符对应的数字,转换为字节序列。
Go语言中字符串的声明和初始化非常简单,举例如下:
fmt.Println(utf8.RuneCountInString("中国")) //out:2
注:
- 双引号-可以识别转义字符;
- 反引号-以字符串的原生形式输出,包括换行和特殊字符,可以实现防止攻击、输出源码等功能;
- 单引号-表示字节。
1、字符串操作
fmt.Println(utf8.RuneCountInString("中国")) //out:2
2、计算字符串长度
内建函数len()的返回值的类型为int,表示字符串的ASCII字符个数或字节长度。
len('中国') // out:6
使用utf8包的RuneCountInString()函数统计Unicode字符数量。
fmt.Println(utf8.RuneCountInString("中国")) //out:2
总结:
- ASCII字符串长度使用len()函数。
- Unicode字符串长度使用utf8.RuneCountInString()函数。
3、字符串遍历
Go语言支持两种方式遍历字符串。
一种是以字节数组的方式遍历:
str := "Hello,世界"n := len(str)for i := 0; i < n; i++ { ch := str[i] // 依据下标取字符串中的字符,类型为byte fmt.Println(i, string(ch))}
另一种是以Unicode字符遍历:
str := "Hello,世界"for i, ch := range str { fmt.Println(i, string(ch)) //ch的类型为rune}
总结:
- ASCII字符串遍历直接使用下标。中文会乱码。
- Unicode字符串遍历用for range。中文正常。
4、strings包操作字符串
5、修改字符串
字符串是不可变的,只能通过重新构造新的字符串并赋值给原来的字符串变量实现。
修改字符串时,可以将字符串转换为[]byte进行修改。
[]byte和string可以通过强制类型转换互转。
6、连接字符串
使用"+"对字符串进行连接操作,但不高效。
使用StringBuilder进行高效的字符串连接。
示例:
a := "hello"b := "world"var s bytes.Buffer // 声明字节缓冲区s.WriteString(a)s.WriteString(" ")s.WriteString(b)fmt.Println(s.String()) // out: hello world
bytes.Buffer 是可以缓冲并可以往里面写入各种字节的数组。字符串也是一种字节数组,使用WriteString()方法进行写入。
将需要连接的字符串,通过调用WriteString()方法,写入stringBuilder 中,然后再通过s.String()方法将缓冲转换为字符串。
7、格式化
fmt.Sprintf(格式化样式,参数列表)
fmt.Printf(格式化样式,参数列表)
// 格式化布尔型变量 fmt.Printf("%t", true) // 使用`%p`输出一个指针的值 fmt.Printf("%p", &p) // 你也可以指定浮点数的输出宽度,同时你还可以指定浮点数的输出精度 fmt.Printf("|%6.2f|%6.2f|", 1.2, 3.45) // 你也可以指定输出字符串的宽度来保证它们输出对齐。默认是右对齐的 fmt.Printf("|%6s|%6s|", "foo", "b") // 为了使用左对齐你可以在宽度之前加上`-`号 fmt.Printf("|%-6s|%-6s|", "foo", "b") // 左对齐并在%v的基础上,对结构体字段名和值进行展开 fmt.Sprintf("%-15s: %+-v", "Labels", item.Labels) // 输出像Go源码中那样带双引号的字符串,需使用`%q` fmt.Printf("%q", ""string"")
字符类型
Golang中没有专门的字符类型,如果要存储单个字符(字母),一般使用byte来保存。
字符串中的每一个元素叫做"字符"。在遍历或者单个获取字符串元素时可以获得字符。
字符串就是一串固定长度的字符连接起来的字符序列。Go的字符串是由单个字节连接起来的。也就是说对于传统的字符串是由字符组成的,而go的字符串不同,它是由字节组成的。
Go语言的字符有以下两种:
- 一种是uint8类型,或者叫byte型,代表了ASCII码的一个字符。
- 另一种是rune类型,代表了一个UTF-8字符。当需要处理中文时则需要用到rune类型。rune类型实际是一个int32.
说明:
- 如果保存的字符在ASCII表的,比如[0-1,a-z,A-Z]可以直接保存到byte,
var c1 byte = 'a'fmt.Println(c1) // out: 97
- 如果保存的字符对应码大于255,可以考虑使用int类型保存。
- 如果需要按照字符的方式输出,需要格式化输出,即
fmt.Printf("%c",c1) // out: a
- 字符常量是用单引号括起来的单个字符。
var c1 byte='a'var c2 int = '中'var c3 byte='7'
- Go 语言的字符使用UTF-8编码,英文字母1个字节,汉字3个字节。
- 在Go中,字符的本质是一个整数,直接输出时,是该字符对应的UTF-8编码的码值。
- 可以直接给某个变量赋值一个数字,然后格式化输出时%c,会输出该数字对应的Unicode字符。
var c1 int = 22269fmt.Printf("c1=%c",c1) //out: c1=国
- 字符类型是可以进行运算的,相当于一个整数,因为它都有对应的Unicode码。
var n1 = 10 + 'a'
字符类型本质
1)字符型存储到计算机中,需要将字符对应的码值(整数)找出来
存储:字符--->对应码值--->二进制--->存储
读取:二进制--->码值--->字符--->读取
2)字符和码值的对应关系是通过字符编码表决定的(是规定好的)