go语言rune、[]byes、string
字符编码
在讲述三种类型前,首先要明确字符编码的几个概念
1 ASCII
最早只有127个字母被编码到计算机里,即ASCII码的127个字符,包括英文大小写、数字及符号。
缺点:只适用于英文编码,与其它国家语言字符不兼容。
优点:占用空间小。
2 Unicode
解决了不同国家编码兼容的性问题,Unicode将不同编码统一到一个格式当中
缺点:占用内存大,纯英文编码比ASCII大一倍内存占用空间。
优点:解决编码统一性问题。
3 UTF-8
可变长度Unicode编码,用于解决Unicode占用空间较大的问题,一般中文字符占用3个字节,英语占用一个字节。
优点:降低Unicode的空间资源消耗。
Go语言字符类型
Go语言源文件采用UTF8编码(UTF8编码也是由Go语言之父,Ken Thompson和RobPike共同发明)
字符串String
Go语言中string
是只读的,不能修改,为了保证其可读性,对于string
类型转化时,往往新生成一个底层数组。
输入:
b := "你好,世界"
fmt.Printf("b[1]=%s,len(b)=%d,type=%T,b=%s\n",b[1],len(b),b,b)
输出:
b[1]=%!s(uint8=189),len(b)=15,type=string,b=你好,世界
可以看出通过数组b[1]
取出来的并不是"你"
字符,其类型是uint8
,表示单个字节,byte
也是uint8
的别名。
字符rune
看下面这个例子
输入
c := []rune(b)
fmt.Printf("c[1]=%s,len(c)=%d,type=%T,c=%s\n",c[1],len(c),c,c)
输出
c[1]=%!s(int32=22909),len(c)=5,type=[]int32,c=[%!s(int32=20320) %!s(int32=22909) %!s(int32=65292) %!s(int32=19990) %!s(int32=30028)]
c[1]
类型是int32
,c
长度为5,与byte
类型不同的是,rune
类型的值与Unicode码点一一对应。在Go语言中,rune
就是int32
的别名
字节byte
输入
d := []byte(b)
fmt.Printf("d[1]=%s,len(d)=%d,type=%T,d=%s\n",d[1],len(d),d,d)
输出
d[1]=%!s(uint8=189),len(d)=15,type=[]uint8,d=你好,世界
注意:在对byte修改时,一定要字符注意编码格式,字符很可能对应多个字节
总结
rune和byte的作用
当前我的理解是,byte和rune可以区分英文和非英文编码的字符,例如判定当前字符串内是否为中文/英文。
参考
Go语言圣经## go语言rune、[]byes、string
字符编码
在讲述三种类型前,首先要明确字符编码的几个概念
1 ASCII
最早只有127个字母被编码到计算机里,即ASCII码的127个字符,包括英文大小写、数字及符号。
缺点:只适用于英文编码,与其它国家语言字符不兼容。
优点:占用空间小。
2 Unicode
解决了不同国家编码兼容的性问题,Unicode将不同编码统一到一个格式当中
缺点:占用内存大,纯英文编码比ASCII大一倍内存占用空间。
优点:解决编码统一性问题。
3 UTF-8
可变长度Unicode编码,用于解决Unicode占用空间较大的问题,一般中文字符占用3个字节,英语占用一个字节。
优点:降低Unicode的空间资源消耗。
Go语言字符类型
Go语言源文件采用UTF8编码(UTF8编码也是由Go语言之父,Ken Thompson和RobPike共同发明)
字符串String
Go语言中string
是只读的,不能修改,为了保证其可读性,对于string
类型转化时,往往新生成一个底层数组。
输入:
b := "你好,世界"
fmt.Printf("b[1]=%s,len(b)=%d,type=%T,b=%s\n",b[1],len(b),b,b)
输出:
b[1]=%!s(uint8=189),len(b)=15,type=string,b=你好,世界
可以看出通过数组b[1]
取出来的并不是"你"
字符,其类型是uint8
,表示单个字节,byte
也是uint8
的别名。
字符rune
看下面这个例子
输入
c := []rune(b)
fmt.Printf("c[1]=%s,len(c)=%d,type=%T,c=%s\n",c[1],len(c),c,c)
输出
c[1]=%!s(int32=22909),len(c)=5,type=[]int32,c=[%!s(int32=20320) %!s(int32=22909) %!s(int32=65292) %!s(int32=19990) %!s(int32=30028)]
c[1]
类型是int32
,c
长度为5,与byte
类型不同的是,rune
类型的值与Unicode码点一一对应。在Go语言中,rune
就是int32
的别名
字节byte
输入
d := []byte(b)
fmt.Printf("d[1]=%s,len(d)=%d,type=%T,d=%s\n",d[1],len(d),d,d)
输出
d[1]=%!s(uint8=189),len(d)=15,type=[]uint8,d=你好,世界
注意:在对byte修改时,一定要字符注意编码格式,字符很可能对应多个字节
总结
rune和byte的作用
当前我的理解是,byte和rune可以区分英文和非英文编码的字符,例如判定当前字符串内是否为中文/英文。
参考
附:格式化编码表
/*
%v 输出结构体 {10 30}
%+v 输出结构体显示字段名 {one:10 tow:30}
%#v 输出结构体源代码片段 main.Point{one:10, tow:30}
%T 输出值的类型 main.Point
%t 输出格式化布尔值 true
%d`输出标准的十进制格式化 100
%b`输出标准的二进制格式化 99 对应 1100011
%c`输出定整数的对应字符 99 对应 c
%x`输出十六进制编码 99 对应 63
%f`输出十进制格式化 99 对应 63
%e`输出科学技科学记数法表示形式 123400000.0 对应 1.234000e+08
%E`输出科学技科学记数法表示形式 123400000.0 对应 1.234000e+08
%s 进行基本的字符串输出 "\"string\"" 对应 "string"
%q 源代码中那样带有双引号的输出 "\"string\"" 对应 "\"string\""
%p 输出一个指针的值 &jgt 对应 0xc00004a090
% 后面使用数字来控制输出宽度 默认结果使用右对齐并且通过空格来填充空白部分
%2.2f 指定浮点型的输出宽度 1.2 对应 1.20
%*2.2f 指定浮点型的输出宽度对齐,使用 `-` 标志 1.2 对应 *1.20
*/