Go语言圣经第三章-基础数据类型
3.1 整型
^操作符在go中有两个作用:
- 作为两元操作符时:x ^ y,按位异或,不同为1,相同为0
- 作为前置应让运算符:^y,按位取反
&^: z= x &^ y, 如果y在某个位置是1,就把x对应位置的数归零,如果y在某个位置是0,x对应的数字不变
1 | fmt.Printf("%d %[1]o %#[1]o\n", o) |
- %[1]o: 以八进制打印第一个参数,[1]的意思是读取第一个参数,好处是不用多次传同一个参数
- #: 对于对应进制会在前面强制补零
字符使用%c打印,带单引号的字符使用%q打印
1 | ascii := 'a' |
3.2 浮点数
math提供了正无穷和负无穷,用于表示太大溢出的数字和除零的结果,以及NaN非数,一般用于表示无效的除法操作,或者Sqrt(-1)
3.4 布尔型
布尔值可以和&&(AND)和||(OR)操作符结合,并且有短路行为:如果运算符左边值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值
&&的优先级比||高(助记:&&对应逻辑乘法,||对应逻辑加法,乘法比加法优先级要高)
3.5 字符串
字符串是不可变的,不可边指的是无法修改底层存放数据的区域,但是可以让变量指向一块新的内存区域
1 | s := "left foot" |
t := s 发生了一次浅拷贝,只复制了s的结构体,s,t都指向同一个内存块,这是字符串拷贝非常快的原因,不用复制底层数据
s += ", right foot",在内存中找一个新地址,先把旧数据复制过去,然后再把新的数据追加过去,然后更新s,最后的结果就是,s指向了新的地址,t指向的还是原来的地址
ASCII控制代码转义方式:
1 | \a 响铃 |
UTF-8
定长编码(UTF-32):不管是字母A,还是复杂的汉字,通通占用4个字节,这很浪费空间
变长编码(UTF-8):
如果是 ASCII 字符(英文、数字):只占用 1 个字节。
如果是 常用字符(比如部分欧洲文字):占用 2 个字节。
如果是 汉字、日文:通常占用 3 个字节。
如果是 Emoji 表情:占用 4 个字节。
UTF-8利用每个字节的前面几位来标识这个字节是否读完了
- 以0开头:告诉电脑结束了,这是一个完整的字符,保证了兼容性,可以兼容老旧的ASCII文件
- 多个字节:
- 110:表示后面还有一个字节(2字节)
- 1110:后面还有2个字节(3字节)
- 11110:后面还有3个字节(4字节)
后续的字节以10开头
UTF8解码:显式
1 | for i := 0; i < len(s); { |
调用`DecodeRuneInString返回两个值,r是字符本身,size对应r在采用UTF-8编码后的编码字节数目
隐式:Go的range循环,在处理字符串的时候,会自动隐式解码
如果要将一个字符串解析为整数,可以使用strconv包的Atoi或ParseInt函数,还有用于解析无符号整数的ParseUint函数:
1 | x, err := strconv.Atoi("123") // x is an int |
3.6 常量
- iota常量生成器
第一个声明的常量所在的行,itoa为0, 然后在每一个有声明的行+1
1 | type Weekday int |
原文: “对于一个没有显式类型的变量声明(包括简短变量声明),常量的形式将隐式决定变量的默认类型,无类型整数常量转换为int,它的内存大小是不确定的”
写一个整数不告诉go是什么类型的时候,go会默认转为int类型,int是一个平台相关类型,
在32位系统, int = int32,
在64位系统,int = int64
原文: “但是无类型浮点数和复数常量则转换为内存大小明确的float64和complex128"
go中没有像int那样的通用float类型,所以无论是32还是64位的系统,永远转化为float64
为什么区别对待?
- 整数通常用于数组下标,循环计数,这些操作依赖机器的字长
- 科学计算和数值算法对精度极其敏感。如果在 32 位机器上默认是 float32(精度低),而在 64 位机器上默认是 float64(精度高)。那么对科学计算的影响很大




