开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
1. 引入
string
string 类型的本质是一连串8个bit的字节, string 字符串可以直接转换成[]byte类型
字符串底层是一个byte数组,所以可以和[]byte类型相互转换。字符串是不能修改的 字符串是由byte字节组成,所以字符串的长度是byte字节的长度。
Unicode 和 UTF-8
一开始计算机使用的是ASCII码,ASCII码用7位表示128个字符,包含英文字母,标点符号和数字等
Unicode编码出现,是的能够表示除了英语之外的其他语言,Go代码使用的是UTF-8的编码方式。
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字元编码,它可以用一至四个字节对Unicode字符集中的所有有效编码点进行编码:
| UTF-8 | 所需字节 | 注释 |
|---|---|---|
| 0zzzzzzz(00-7F) | 1个字节 | ASCII字元范围,位元组由零开始 |
| 110yyyyy(C0-DF) 10zzzzzz(80-BF) | 2个字节 | 第一个位元组由110开始,接著的位元组由10开始 |
| 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz | 3个字节 | 第一个位元组由1110开始,接著的位元组由10开始 |
| 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz | 4个字节 | 将由11110开始,接著的位元组由10开始 |
rune的定义
int32的别名,几乎在所有方面等同于int32,它用来区分字符值和整数值
Go 语言的字符有以下两种:
- uint8类型,或者叫 byte 型,代表了ASCII码的一个字符。
- rune类型,代表一个 UTF-8字符。
Go里面双引号是字符串,单引号是字符,rune。
当需要处理中文、日文或者其他复合字符时,则需要用到rune类型。UTF8编码下一个中文汉字由3~4个字节组成,所以我们不能简单的按照字节去遍历一个包含中文的字符串。
rune类型实际是一个int32。rune类型用来表示utf8字符,一个rune字符由一个或多个byte组成。
举个例子
s := "hello 你好"
fmt.Println(len(s),reflect.TypeOf(s)) // 打印变量s的长度和类型 12 string
fmt.Printf(""%s"'s type is %T",s,s)// "hello 你好"'s type is string
中文字符在uincode下面占2个字节,在utf-8编码下面占3个字节,Go代码使用的是UTF-8的编码方式。所以字符串总的长度是12,5(hellp)+1(空格)+6(两个中文字2*3)
2. 操作
A 修改字符串
要修改字符串,需要先将其转换成[]rune或[]byte,完成后再转换为string。无论哪种转换,都会重新分配内存,并复制字节数组。
B 遍历字符串
for _,v := range s {
fmt.Printf(" "%v"'s type is %T \n",v,v)
}
结果
"104"'s type is int32
"101"'s type is int32
"108"'s type is int32
"108"'s type is int32
"111"'s type is int32
"32"'s type is int32
"20320"'s type is int32
打印出来的类型是rune
C 打印变量的两种方法
1.使用reflect的TypeOf方法
s := "hello world"
fmt.Println(len(s),reflect.TypeOf(s)) // 打印变量s的长度和类型 11 string
2. 使用Printf中的占位符%T
fmt.Printf(""%s"'s type is %T",s,s) // "hello world"'s type is string
%d 十进制 %T 查看类型 %v 查看值(任何类型都可以调用) %b 二进制 %o 八进制 %x 十六进制 %s 字符串 %f 浮点数
3. 总结
- Rune 是golang中的一种数据类型,底层类型是int32,用来存储unicode code-point.
- 两种方式可以打印变量的类型,占位符%T和reflect.TypeOf()方法