Go基本数据类型----布尔类型与数字类型
Go基本数据类型----布尔类型与数字类型
运算符
下面是 Go 语言中支持的运算符号的优先级排列
Precedence Operator 5 * / % << >> & &^ 4 + - | ^ 3 == != < <= > >= 2 && 1 ||
-
&&
和||
操作符有短路行为:如果运算符左边值已经可以确定整个布尔表达式的值,那么运算符右边的值将不再被求值 -
对于上表中前两行的运算符,例如
+
运算符还有一个与赋值相结合的对应运算符+=
,可以用于简化赋值语句。 -
Go 语言中没有自增与自减运算符,它们被降级为了语句
statement
,并且规定了只能位于操作数的后方,所以不用再去纠结i++
和++i
这样的问题。a++ // 正确 ++a // 错误 a-- // 正确 还有一点就是,它们不再具有返回值,因此
a = b++
这类语句的写法是错误的。 -
算术运算符
+
、-
、*
和/
可以适用于整数、浮点数和复数,但是取模运算符%
仅用于整数间的运算。并且%
取模运算符的符号和被取模数的符号总是一致的,因此-5%3
和-5%-3
结果都是-2
。 -
除法运算符
/
的行为则依赖于操作数是否全为整数,比如7.0/4.0
的结果是1.75
,但是7/4
的结果是1
。 -
一个算术运算的结果,不管是有符号或者是无符号的,如果需要更多的 bit 位才能正确表示的话,就说明计算结果是溢出了,并且超出的高位的 bit 位部分将被丢弃,但不会报错。如果原始的数值是有符号类型,而且最左边的 bit 位是 1 的话,那么最终结果可能是负的,例如
int8
的例子:var u uint8 = 255 fmt.Println(u, u+1, u*u) // "255 0 1" var i int8 = 127 fmt.Println(i, i+1, i*i) // "127 -128 1" -
所有的二元运算符都需要操作数的类型相同,即便是
int32
和int64
也不能直接进行加分操作,所以如果想要运行成功只能使用显示的类型转换var a int32 = 10 var b int64 = 20 d := a + b // invalid operation: a + b (mismatched types int32 and int64) c := int64(a) + b // 正确
数据类型
布尔类型
类型 | 描述 |
---|---|
bool | true 为真值,false 为假值,默认值为 false |
在 Go 语言中,布尔型、数字类型和字符串等基本类型都是可比较的,即两个相同类型的值可以用 ==
和 !=
进行比较,得到布尔类型的结果。此外,整数、浮点数和字符串可以通过大小比较运算( >
、 <
等)比较大小,结也会得到布尔类型的结果。许多其它类型的值可能是不可比较的,因此也就可能是不可排序的。
var aVar = 10 // 二元运算符进行相等比较 aVar == 5 -> false aVar == 10 -> true // 二元运算符进行不等比较 aVar != 5 -> true aVar != 10 -> false
除此之外,还有上一部分我们提到的 &&
和 ||
运算符(短路行为),以及一元运算符 !
!T -> false !F -> true // 只有两边的值都为 true ,结果才是 true;否则结果为false T && T -> true T && F -> false F && T -> false F && F -> false //只有两边的值都为 false ,结果才是 false;否则结果为 true T || T -> true T || F -> true F || T -> true F || F -> false
在 Go 中,整数 0 并不代表假值,非零整数也不能代表真值,即数字无法代替布尔值进行逻辑判断,两者是完全不同的类型。
但是我们可以用下面两个函数完成 bool
和 int
类型的相互转换
// btoi returns 1 if b is true and 0 if false. func btoi(b bool) int { if b { return 1 } return 0 } // itob reports whether i is non-zero. func itob(i int) bool { return i != 0 }
数字类型
Go 语言支持整型和浮点型数字,并且原生支持复数。
整型
整型的零值(默认值)为 0
种类 | 符号 | 数据类型 | 类型宽度(bit) | 备注 |
---|---|---|---|---|
int |
有 | int | 32 或 64 | 与计算机系统的位数有关 |
有 | int8 | 8 | ||
有 | int16 | 16 | ||
有 | int32 | 32 | 相当于 32 位系统下的 int 类型 | |
有 | int64 | 64 | 相当于 64 位系统下的 int 类型 | |
uint |
无 | uint | 32 或 64 | 与计算机系统的位数有关 |
无 | uint8 | 8 | ||
无 | uint16 | 16 | ||
无 | uint32 | 32 | 相当于 32 位系统下的 uint 类型 | |
无 | uint64 | 64 | 相当于 64 位系统下的 uint 类型 | |
无 | uintptr | 是一个足够大的整数类型,足以容纳任何位数的整数指针(特殊用途)。 |
int 并没有指定它的位数,说明它的大小,是可以变化的,那根据什么变化呢?
- 当你在 32 位的系统下,
int
和uint
都占用 4 个字节,也就是 32 位。- 若你在 64 位的系统下,
int
和uint
都占用 8 个字节,也就是 64 位。出于这个原因,在某些场景下,你应当避免使用
int
和uint
,而使用更加精确的int32
和int64
无符号数往往只有在位运算或其它特殊的运算场景才会使用,就像 bit 集合、分析二进制文件格式或者是哈希和加密操作等。它们通常并不用于仅仅是表达非负数量的场合
bit位运算
位运算只能用于整数类型的变量,且需当它们拥有等长位模式时。
& 位运算 AND | 位运算 OR ^ 位运算 XOR &^ 位清空(AND NOT) << 左移 >> 右移
-
按位与
&
:在 Go 中,
&
运算符在两个整型操作数中执行按位AND
操作。AND
操作具有以下属性:Given operands a, b AND(a, b) = 1; only if a = b = 1 else = 0 -
按位或
|
:
|
运算符在两个整型操作数中执行按位OR
操作。OR
操作具有以下属性:Given operands a, b OR(a, b) = 1; when a = 1 or b = 1 else = 0 -
按位异或
^
:
^
运算符在两个整型操作数中执行按位XOR
操作。XOR
操作具有以下属性:Given operands a, b XOR(a, b) = 1; only if a != b else = 0 -
与非
&^
:
&^
运算符在两个整型操作数中执行按位AND_NOT
操作。AND_NOT
操作具有以下属性:Given operands a, b AND_NOT(a, b) = AND(a, NOT(b)) /* 若b=1 */ AND_NOT(a, 1) = 0; clears a AND_NOT(a, 0) = a; -
按位取反
^
:该运算符与异或运算符一同使用,即
m^x
,对于无符号x
使用m=
“全部位设置为 1”,对于有符号x
时使用m=-1
(全部位也都为1)。^10 = -01 ^ 10 = -11 -
位左移
<<
与 位右移>>
:Go 使用
<<
和>>
来表示左移运算符和右移运算符,如下所示:Given integer operands a and n, a << n; shifts all bits in a to the left n times a >> n; shifts all bits in a to the right n times 注意:左移符每次移动都会将低位右侧补零,相对应,使用右移位操作符进行运算时,每个位均向右方移动,空出的高位补零。因为这个原因,最好用无符号整数运算,这样你可以将整数完全当作一个bit位模式处理。
浮点型
浮点型的零值(默认值)为0.0
类型 | 精度位数 | 类型和描述 |
---|---|---|
float32 | 小数点后 6 位 | IEEE-754 32 位浮点型数,单精度 |
float64 | 小数点后 15 位 | IEEE-754 64 位浮点型数,双精度 |
由于浮点数精确度的缘故,你在使用 ==
或者 !=
来比较时应当非常小心。
通常应该优先使用
float64
类型,因为float32
类型的累计计算误差很容易扩散,并且float32
能精确表示的正整数并不是很大(译注:因为float32
的有效 bit 位只有 23 个,其它的 bit 位用于指数和符号;当整数大于23bit
能表达的范围时,float32
的表示将出现误差)。一个更重要的原因是math
包中所有有关数学运算的函数都会要求接收float64
类型。
以下是float32
精度不足而引起的判断错误
import "fmt" var myfloat01 float32 = 100000182 var myfloat02 float32 = 100000187 func main() { fmt.Println("myfloat: ", myfloat01) fmt.Println("myfloat: ", myfloat01+5) fmt.Println(myfloat02 == myfloat01+5) } /* 输出结果: myfloat: 1.00000184e+08 myfloat: 1.0000019e+08 false */
复数类型
类型 | 描述 |
---|---|
complex128 | 64 位实数和虚数 |
complex64 | 32 位实数和虚数 |
复数使用 re+im i
来表示,其中 re
代表实数部分,im
代表虚数部分,i
代表根号负 1。下面我们用两种方法构建复数类型变量:
var c1 complex64 = 5 + 10i fmt.Printf("The value is: %v", c1) // 输出: 5 + 10i re, im := 5.1, 10.1 c := complex(re, im) fmt.Println(c) // 输出: 5.1 + 10.1i
在Go语言中,存在两个内建的函数---- real(c)
和 imag(c)
可以分别获得相应的实数和虚数部分。
var x complex128 = complex(1, 2) // 1+2i var y complex128 = complex(3, 4) // 3+4i fmt.Println(x*y) // "(-5+10i)" fmt.Println(real(x*y)) // "-5" fmt.Println(imag(x*y)) // "10"
如果你对内存的要求不是特别高,最好使用
complex128
作为计算类型,因为math
包中相关函数都使用这个类型的参数。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律