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包中相关函数都使用这个类型的参数。

浙公网安备 33010602011771号