Go总结(一)| 数据类型的本质
每种编程语言都设计了自己的数据类型系统,数据类型的本质是什么?
我上大学才开始接触计算机的概念(太晚了),老师说现代计算机叫存储程序式计算机(冯诺依曼体系结构),现在我更直白的理解就是计算机是由CPU + IO设备组成的。IO设备就是数据,CPU就是对这些数据进进出出一顿算。我们常说的内存是IO设备的一种,IO设备种类繁多不好说清楚问题,这里我们假设计算机只有CPU和内存;CPU不停从内存取数据,再将计算结果写到内存,这个过程乐此不疲的进行着,而且速度极快。
编程语言的数据类型本质就是内存空间。
当然一样的内存空间,在不同CPU体系架构下意义可能是不一样的,要看约定规则是什么。
有了内存空间和解析规则,里面由bit
位(0或者1)组合表示的数据就有意义了。他们可能用来表示数值、指令、或者其它内存的地址等。
PS:不是所有的值都有地址,因为可能只存在于CPU寄存器中;但是所有的变量都有地址。
计算机内存管理相关知识,参考这篇文章,很详细:https://www.jianshu.com/p/0851a951a46e
Go语言的数据类型
按一般感观分成四大类:
- 基础类型:
boolean、number、string
- 聚合类型:
array、struct
- 引用类型:
pointer、slice、map、channel、func
- 接口类型:
interface
除了基础数据类型number之外,其它类型都可以看做是基础数据类型的派生类型。
如果按变量存放的数据意义,1、2为值类型,3、4为引用类型。
常量
所谓常量,也就是在程序编译阶段就确定下来的值,而程序在运行时则无法改变该值。在Go语言程序中,常量可定义为数值、布尔值或字符串等类型。
Boolean
布尔值的类型为bool
,值是true
或false
,默认为false
。
数值
数值(number)分整型和浮点型;整型又分有符号和无符号两种。同时支持int
和uint
,这两种类型的长度相同,但具体长度取决于不同编译器的实现。Go语言里面也有直接定义好位数的类型:rune,int8,int16,int32,int64
和byte,uint8,uint16,uint32,uint64
。其中rune
是int32
的别称,byte
是uint8
的别称。
类型 | 描述 |
---|---|
uint |
32位或64位 |
uint8 |
无符号 8 位整型 (0 到 255) |
uint16 |
无符号 16 位整型 (0 到 65535) |
uint32 |
无符号 32 位整型 (0 到 4294967295) |
uint64 |
无符号 64 位整型 (0 到 18446744073709551615) |
int |
32位或64位 |
int8 |
有符号 8 位整型 (-128 到 127) |
int16 |
有符号 16 位整型 (-32768 到 32767) |
int32 |
有符号 32 位整型 (-2147483648 到 2147483647) |
int64 |
有符号 64 位整型 (-9223372036854775808到9223372036854775807) |
byte |
uint8 的别名 (type byte = uint8) |
rune |
int32 的别名 (type rune = int32) ,表示一个 unicode 码 |
uintptr |
类似uint ;底层编程时使用,特别是Go与C函数库或操作系统接口交互的地方 |
float32 |
IEEE-754 32位浮点型数 |
float64 |
IEEE-754 64位浮点型数 |
complex64 |
32 位实数和虚数 |
complex128 |
64 位实数和虚数 |
字符串
字符串都是采用UTF-8
字符集编码。字符串是用一对双引号(")或一对反引号(`)括起来定义,它的类型是string。
数组
数据表示某类型固定长度的空间,一旦声明长度不可改变。
|
|
结构
|
|
指针
|
|
切片
|
|
映射
|
|
通道
|
|
函数
|
|
接口
|
|
error类型
内置error
类型是一个interface
,专门用来处理错误信息,Go的package里面还专门有一个包errors来处理错误。
|
|
值类型和引用类型
值类型
变量直接存储的值,内存通常在栈中分配。
引用类型
指变量存储的是实际数据的描述信息,这段信息被称作标头(header)
。标头中通常有实际值的起始地址指针,当前大小、最大容量等信息。实际值通常在堆中分配,当实际值没有任何标头引用的时候,其对应的内存空间将被GC
自动回收。
每个引用类型创建的标头值是包含一个指向底层数据结构的指针。每个引用类型还可能包含一组独特的字段,用于管理底层数据结构。因为标头值是为复制而设计的,所以永远不需要共享一个引用类型的值。标头值里包含一个指针,因此通过复制来传递一个引用类型的值的副本,本质上就是在共享底层数据结构。
引用类型声明变量通常有两种方式:make 或 new
,make
用于内建类型(map、slice、channel等)
的内存分配;new
实际可以用于各种类型的内存分配;按照Go的约定,用make和new声明的变量都会自动初始化为各自基础数据类型的零值。对声明引用类型变量来说:
- make只能用在(map|channel|slice),返回类型标头,标头至少包含一个值地址指针,有的还包含其它描述字段。
- new返回的是类型指针,指针指向类型值的起始地址
看一下源代码的定义就知道了:
|
|
(完)
- 原文作者: 闪电侠
- 原文链接:https://chende.ren/2020/11/25121301-001-all-types.html
- 版权声明:本作品采用 开放的「署名 4.0 国际 (CC BY 4.0)」创作共享协议 进行许可