一、Go 的数据类型
Go 中的数据类型分为值类型和引用类型,值类型与引用类型的区别是值类型存储的值,变量直接指向值,而引用类型存储的是内存地址,通过内存地址指向具体的值。
值类型包括了整数类型、浮点数类型、布尔类型、字符串类型、数组类型以及结构体类型
- 整数类型 int,包含正数和负数,没有小数点部分或者小数点的数字,默认是十进制,也可以是其他进制;
- 浮点类型 float,存储包含小数或小数部分的数字,有正负之分;
- 布尔类型 bool,只包含 TRUE 和 FALSE 两个值;
- 字符串类型 string,内置类型,由多个字符组成,默认值为"";
- 数组类型 array,具有相同唯一类型的一组已编号且长度固定的数据项序列;
- 结构体类型 struct,用户自定义的类型,用于描述实体对象,类似面向对象编程语言中的类;
引用数据类型有映射 map 类型、指针类型、切片 slice 类型、channel 类型、接口 interface 和函数 function 类型。
- 映射类型 map,无序的、键值对的集合;
- 指针类型 pointers,计算机内存中变量所在的内存地址;
- 切片类型 slice,数组的抽象;
- 管道 channel,用于实现并行计算方程间通信;
- 接口 interface,一组方法签名的集合;
- 函数 function,不支持嵌套、重载和默认参数;
二、数值类型
整数
Go 中整数类型分为有符号和无符号两种,并且按照长度或者可存储的范围分为:
- 有符号整数:int8、int16、int32、int64
- 无符号整数:uint8、uint16、uint32、uint64
有符号整数所占用的字节数和可表示的范围:
| 类型 | 占用字节 | 范围 |
|---|---|---|
| int8 | 1 | -128 ~ 127 |
| int16 | 2 | -32768 ~ 32767 |
| int32 | 3 | -2147483648 ~ 2147483647 |
| int64 | 4 | -9223372036854775808 ~ 9223372036854775807 |
| int | 4 | -9223372036854775808 ~ 9223372036854775807 |
无符号整数所占用的字节数和可表示的范围:
| 类型 | 占用字节 | 范围 |
|---|---|---|
| uint8 | 1 | 0 ~ 255 |
| uint16 | 2 | 0 ~ 65535 |
| uint32 | 3 | 0 ~ 4294967295 |
| uint64 | 4 | 0 ~ 18446744073709551615 |
在 go-quickstart 项目中新建一个文件夹 02-数据类型 用于存放数据类型相关的 Go 文件。
func main() {
var zulu int8 = 38
var yankee int16 = 250
var xray int32 = 9527
var whiskey int64 = 12138
var victor int = 86
// 通过 Printf 函数 和 %v,%T 占位符来输出 值Value 和 类型Type
fmt.Printf("%v, %T\n", zulu, zulu)
// 通过 reflect.TypeOf 函数来输出 类型
fmt.Println(reflect.TypeOf(yankee))
// 输出所占字节数
fmt.Println("int8所占字节数为:", unsafe.Sizeof(zulu))
fmt.Println("int16所占字节数为:", unsafe.Sizeof(yankee))
fmt.Println("int32所占字节数为:", unsafe.Sizeof(xray))
fmt.Println("int64所占字节数为:", unsafe.Sizeof(whiskey))
fmt.Println("int所占字节数为:", unsafe.Sizeof(victor))
// 输出范围
fmt.Println("int8可表示范围是:", math.MinInt8, math.MinInt8)
fmt.Println("int16可表示范围是:", math.MinInt16, math.MaxInt16)
fmt.Println("int32可表示范围是:", math.MinInt32, math.MaxInt32)
fmt.Println("int64可表示范围是:", math.MinInt64, math.MaxInt64)
fmt.Println("int可表示范围是:", math.MinInt, math.MaxInt)
}
执行上述代码,输出结果如下:
38, int8
int16
int8所占字节数为: 1
int16所占字节数为: 2
int32所占字节数为: 4
int64所占字节数为: 8
int所占字节数为: 8
int8可表示范围是: -128 -128
int16可表示范围是: -32768 32767
int32可表示范围是: -2147483648 2147483647
int64可表示范围是: -9223372036854775808 9223372036854775807
int可表示范围是: -9223372036854775808 9223372036854775807
在上述代码中,分别使用到了 fmt 包下的 Printf 函数,该函数可以用于格式化输出,其中
%v:表示输出变量保存的值%T:表示输出变量的类型
reflect 包下的 Typeof 函数也可以输出变量的类型,unsafe 包下的 Sizeof 可以输出变量保存的数据类型所占用的字节数,math 包下的 MinInt 和 MaxInt 则可以输出 int 数据类型的最小值和最大值。
浮点数
浮点数按照精度划分为 float32 和 float64,日常使用频率较高的是 float64,因为 float32 累计计算误差已扩散。
// package 和 import 省略
func main() {
var uniform float32 = 38
var tango float64 = 250
// 通过 Printf 函数 和 %v,%T 占位符来输出 值Value 和 类型Type
fmt.Printf("%v, %T\n", uniform, uniform)
// 通过 reflect.TypeOf 函数来输出 类型
fmt.Println(reflect.TypeOf(tango))
// 输出所占字节数
fmt.Println("float32所占字节数为:", unsafe.Sizeof(uniform))
fmt.Println("float64所占字节数为:", unsafe.Sizeof(tango))
// 输出范围
fmt.Println("float32可表示最大值是:", math.MaxFloat32)
fmt.Println("float64可表示最大值是:", math.MaxFloat64)
}
执行上述代码,输出结果如下:
38, float32
float64
float32所占字节数为: 4
float64所占字节数为: 8
float32可表示最大值是: 3.4028234663852886e+38
float64可表示最大值是: 1.7976931348623157e+308
复数
Go 中还内置了 complex64 和 complex128 两种数据类型用于存储复数,创建复数时要使用 complex 函数,该函数有两个入参,第一个表示复数的实部,第二个表示复数的虚部
// package, import 代码省略
func main() {
var sierra complex64 = complex(1, 2)
var romeo complex128 = complex(100, 200)
// 通过 Printf 函数 和 %v,%T 占位符来输出 值Value 和 类型Type
fmt.Printf("%v, %T\n", sierra, sierra)
// 通过 reflect.TypeOf 函数来输出 类型
fmt.Println(reflect.TypeOf(romeo))
//// 输出所占字节数
fmt.Println("complex64所占字节数为:", unsafe.Sizeof(sierra))
fmt.Println("complex128所占字节数为:", unsafe.Sizeof(romeo))
// 输出实部和虚部
fmt.Printf("siere 变量的实部是 %v,虚部是 %v", real(sierra), imag(sierra))
}
执行上述代码,输出结果如下:
(1+2i), complex64
complex128
complex64所占字节数为: 8
complex128所占字节数为: 16
siere 变量的实部是 1,虚部是 2
real 函数 和 imag 函数可以获取复数的实部和虚部
三、布尔值
Go 中通过 bool 关键字声明布尔类型数据,布尔类型有 true 和 false 两个值,默认值为 false
func main() {
var quebec bool = true
// 通过 Printf 函数 和 %v,%T 占位符来输出 值Value 和 类型Type
fmt.Printf("%v, %T\n", quebec, quebec)
//// 输出所占字节数
fmt.Println("bool 所占字节数为:", unsafe.Sizeof(quebec))
}
执行上述代码,输出结果如下:
true, bool
bool 所占字节数为: 1
与其他语言中的布尔类型有所不同的是:
- Go 语言中不允许整数或其他数据类型和布尔类型之间的转换
- Go 语言中布尔类型无法与数值进行运算