机器级程序将内存视为一个非常大的字节数组,称为虚拟内存(virtual memory)。内存的每个字节都由一个唯一的数字来标识,称为它的地址(address),所有可能地址的集合就称为虚拟地址空间(virtual memory space)

所以,从内存管理上看,编程语言中的数据类型表示的是存储的何种类型的数据,就是一个类型占用的内存大小。也就是说,数据类型的出现是为了把数据分成所需内存大小不同的数据

在程序中,我们通过指定其类型,能实现以特定字节数为单位来进行读写。

Go语言提供了丰富的数据组织形式,其数据类型可以分为四类:基础类型、复合类型、引用类型和接口类型。这里,我们将探索最基础的一类—基础数据类型。
总的来说,基本的数据类型有如下几种:
基本类型

数字类型

int8int16int32int64uint8uint16uint32uint64

示例:

在这里插入图片描述

intint64int
1 Byte(字节) = 8 b(bit)
1 KB = 1024 B
1 MB = 1024 KB
1 GB = 1024 MB
int

无符号数的编码

假设有一个整数数据类型有 w w w 位,我们将位向量写成 x ⃗ \vec{x} x ,表示整个向量,或写成 [ x w − 1 , x w − 2 , . . . , x 0 ] [x_{w-1},x_{w-2},...,x_0] [xw−1​,xw−2​,...,x0​] ,表示向量中的每一位。把 x ⃗ \vec{x} x 看成一个二进制表示的数,就获得了 x ⃗ \vec{x} x 的无符号表示。由于是无符号,则不需要考虑负数的情况,于是有,对二进制向量:
x ⃗ = [ x w − 1 , x w − 2 , . . . , x 0 ] \vec{x} = [x_{w-1},x_{w-2},...,x_0] x =[xw−1​,xw−2​,...,x0​]
有:
B 2 T w ( x ⃗ ) = ∑ i = 0 w − 1 x i 2 i B2T_w(\vec x) = \sum_{i=0}^{w-1} x_{i}2^i B2Tw​(x )=i=0∑w−1​xi​2i
举个例子:
B 2 T 4 ( [ 0101 ] ) = 0 ⋅ 2 3 + 1 ⋅ 2 2 + 0 ⋅ 2 1 + 1 ⋅ 2 0 = 0 + 4 + 0 + 1 = 5 B 2 T 4 ( [ 1011 ] ) = 1 ⋅ 2 3 + 0 ⋅ 2 2 + 1 ⋅ 2 1 + 1 ⋅ 2 0 = 8 + 0 + 2 + 1 = 11 \begin{aligned} B2T_4([0101]) &= 0\cdot2^3 + 1 \cdot2^2 + 0\cdot2^1 + 1\cdot2^0 = 0 + 4 + 0 + 1 = 5 \\ B2T_4([1011]) &= 1\cdot2^3 + 0 \cdot2^2 + 1\cdot2^1 + 1\cdot2^0 = 8 + 0 + 2 + 1 = 11 \end{aligned} B2T4​([0101])B2T4​([1011])​=0⋅23+1⋅22+0⋅21+1⋅20=0+4+0+1=5=1⋅23+0⋅22+1⋅21+1⋅20=8+0+2+1=11​

补码编码

在许多应用中,我们希望表示负数值。最常见的有符号的计算表示方式就是 补码 形式。在这个定义中,将字的最高位解释为 负权(negative weight):

对二进制向量:
x ⃗ = [ x w − 1 , x w − 2 , . . . , x 0 ] \vec{x} = [x_{w-1},x_{w-2},...,x_0] x =[xw−1​,xw−2​,...,x0​]
有:
B 2 T w ( x ⃗ ) = − x w − 1 2 w − 1 + ∑ i = 0 w − 2 x i 2 i B2T_w(\vec x) = -x_{w-1}2^{w-1} + \sum_{i=0}^{w-2} x_{i}2^i B2Tw​(x )=−xw−1​2w−1+i=0∑w−2​xi​2i
其中,最高有效位 w − 1 w-1 w−1 也称为 符号位,当值为 1 时,表示负值,当值为 0 时,表示非负。我们可以看看例子:
B 2 T 4 ( [ 0101 ] ) = − 0 ⋅ 2 3 + 1 ⋅ 2 2 + 0 ⋅ 2 1 + 1 ⋅ 2 0 = 0 + 4 + 0 + 1 = 5 B 2 T 4 ( [ 1011 ] ) = − 1 ⋅ 2 3 + 0 ⋅ 2 2 + 1 ⋅ 2 1 + 1 ⋅ 2 0 = − 8 + 0 + 2 + 1 = − 5 \begin{aligned} B2T_4([0101]) &= -0\cdot2^3 + 1 \cdot2^2 + 0\cdot2^1 + 1\cdot2^0 = 0 + 4 + 0 + 1 = 5 \\ B2T_4([1011]) &= -1\cdot2^3 + 0 \cdot2^2 + 1\cdot2^1 + 1\cdot2^0 = -8 + 0 + 2 + 1 = -5 \end{aligned} B2T4​([0101])B2T4​([1011])​=−0⋅23+1⋅22+0⋅21+1⋅20=0+4+0+1=5=−1⋅23+0⋅22+1⋅21+1⋅20=−8+0+2+1=−5​

取值范围

int8
int8 占有 1 Byte,在二进制中是 8 bit
由于是有符号整数,在二进制中,在高位使用 0 或 1 表示正负号: 0--正号,1--负号

于是,最大数为:0 1 1 1 1 1 1 1
根据上面的补码知识,我们可以计算出:
B2T([01111111]) = -0*2^7 + 1*2^6 + 1*2^5 + ... + 1*2^0 = 127
B2T([10000000]) = -1*2^7 + 0*2^6 + 0*2^5 + ... + 0*2^0 = -128

验证如下:

func main() {
	var x int8 = 1
	fmt.Printf("占用字节: %d\n", unsafe.Sizeof(x))  //占用字节: 1
	fmt.Printf("最小值: %d,最大值: %d\n", math.MinInt8, math.MaxInt8)  //最小值: -128,最大值: 127
}

其他的数值也如是计算即可:

go 数据类型最小值最大值
int/int64-92233720368547758089223372036854775807
int8-128127
int16-3276832767
int32-21474836482147483647
uint80255
uint16065535
uint3204294967295
uint64018446744073709551615

浮点数

关于浮点数,本文还没有进行深入的探究,可以参考其他人的文章描述:Golang 笔记之深入浮点数

探究其取值范围:

func main() {
	fmt.Println("双精度浮点数表示正数的最小值是:", math.SmallestNonzeroFloat64)  //5e-324
	fmt.Println("双精度浮点数表示正数的最大值是:", math.MaxFloat64) //1.7976931348623157e+308
}
float64float32

字符类型

string
stringbyterune

我们先看下面一段代码:

func main() {
	var str string = "hello, world"
	var strByte = [...]byte{
		'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd',
	}
	var strRune = [...]rune{
		'h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd',
	}
	fmt.Println([]byte(str))
	fmt.Println(strByte)
	fmt.Println(strRune)  //三者相等
    // [104 101 108 108 111 44 32 119 111 114 108 100],这是Unicode编码10进制的表示
}
string

布尔型

truefalse

使用代码:
在这里插入图片描述

byte

虚数

Go语言提供了两种精度的复数类型:complex64s和complex128,分别对应float32和float64两种浮点数精度。内置的complex函数用于构建复数,内建的real和imag函数分别返回复数的实部和虚部:
在这里插入图片描述