数据类型
值类型和引用类型
在golang中,同其他语言相同,可以将类型大致分为两类:值类型与引用类型。
其中,值类型存储在栈中,他们在编译期就可以确定变量所占用的空间,并且值类型变量直接指向栈空间的值。使用等号=将一个变量的值赋给另一个变量时,如j = i,实际上是在内存中将 i 的值进行了拷贝。我们可以通过 &i 获取变量 i 的内存地址。在golang中,属于值类型的数据类型包含:
数字类型
布尔类型
字符串类型
数组:数组也存放在栈空间中,这个与Java不同
结构体:因为是值传递,所以在方法之间传递会进行值复制,如果结构体较大,需要使用指针
而引用类型拥有更复杂的存储结构,推崇存储在堆内存中,编译时一般无法确定其所占空间:
需要通过make创建并分配内存
初始化一系列属性:指针、长度、哈希分布、数据队列等。一个引用类型的变量
r1存储的是r1的值所在的内存地址(数字),或内存地址中第一个元素所在的位置,这个内存地址被称之为指针,这个指针实际上也被存在另外的某一个变量中。
在golang中,是引用类型的有:
指针
管道 channel
接口 interface
映射 map
函数 function
**值类型在传递参数时,进行值拷贝,引用类型则是引用拷贝。**主要是赋值的区别。
类型零值
零值也就是默认值,当一个类型声明之后没有被初始化,那么他的值就是零值,每种类型都有对应的零值,其中,引用类型对应的零值都为nil:
数字类型,包含整型、浮点型、复数
0
布尔型
false
字符串
""
结构体
结构体中的每个字段都是零值
引用类型:slice, pointer,map,channel,function,interface
nil
nil详解
在Go语言中,布尔类型的零值(初始值)为 false,数值类型的零值为 0,字符串类型的零值为空字符串"",而指针、切片、映射、通道、函数和接口的零值则是 nil。
注意,nil是一个值,像0一样,代表不存在
注意,使用nil,要注意下面几点:
不是关键字和保留字
因为不是关键字和保留字,只是一个标识符,类似int等,所以可以定义一个名称为
nil的变量:没有默认类型
引用类型的零值(初始值)都是nil
不同引用类型的nil值,指针是相同的
不同引用类型的nil值,占用大小不同
两个
nil字面量比较两个值都为
nil的变量不可比较变量(有可能是nil 或者 非nil)可以与nil值比较:
基本数据类型
数值型
整型
无符号整型
uint8
1
0 ~ 255
百
0
uint16
2
0 ~65535
6万多
0
uint32
3
0 ~ 4294967295
40多亿
0
uint64
4
0 ~ 18446744073709551615
大到没有概念
0
uint
系统决定,无符号整型
32位系统位int32,64位系统位int64
0
有符号整型
int8
1
-128 ~ 127
正负百
0
int16
2
-32768 ~ 32767
正负3万多
0
int32
3
-2147483648 ~ 2147483647
正负大20多亿
0
int64
4
-9223372036854775808 ~ 9223372036854775807
正负大到没有概念
0
int
系统决定,有符号整型
32位系统位int32,64位系统位int64
0
字符整型
byte
uint8的别名
用与表示一个ASCII
rune
int32的别名
用于表示一个Unicode代码点
表示一个ASCII:
表示一个Unicode代码点:
浮点型
float32(不常用)
3
IEEE-754 1.401298464324817070923729583289916131280e-45 ~ 3.402823466385288598117041834516925440e+38
精度6位小数
0
float64
4
IEEE-754 4.940656458412465441765687928682213723651e-324 ~ 1.797693134862315708145274237317043567981e+308
精度15位小数
0
复数
我们把形如 z=a+bi(a、b均为实数)的数称为复数。其中,a 称为实部,b 称为虚部,i 称为虚数单位。当 z 的虚部 b=0 时,则 z 为实数;当 z 的虚部 b≠0 时,实部 a=0 时,常称 z 为纯虚数。复数域是实数域的代数闭包,即任何复系数多项式在复数域中总有根。
复数的运算:
加法法则:(a+bi)+(c+di)=(a+c)+(b+d)i`
减法法则:(a+bi)-(c+di)=(a-c)+(b-d)i`
乘法法则:
(a+bi)(c+di)=(ac-bd)+(bc+ad)i除法法则:
complex64
8
(0+0i)
complex128
16
(0+0i)
复数的值由三部分组成 RE + IMi,其中 RE 是实数部分,IM 是虚数部分,RE 和 IM 均为 float 类型,而最后的 i 是虚数单位。
复数的定义和运算:
布尔型
bool
1
true,false
false
字符串
字符串是一个不可变的UTF-8字符序列,并且每个属于ASCII码的字符占用单个字节,其他字符则是占用2-4个字节
不同于C、C++、Java,他们的UTF-8字符长度至少会占用两个字节
Go语言这样做不仅减少了内存和硬盘空间占用,同时也不用像其它语言那样需要对使用 UTF-8 字符集的文本进行编码和解码
双引号字符串支持转义字符
访问字符
字符拼接 "+"
多行字符串
多行字符串中的内容都会原样输出,转义字符不会生效。通常用语内嵌代码或者数据
输出结果为:
类型转换
数值类型相互转换
基本类型 -> string
stringstring->基本类型
string->基本类型派生数据类型
派生数据类型又称为复合数据类型,是由基本类型复合而来。
指针
基本类型也有对应的指针类型
通过&创建指针变量
通过*获取指针变量对应的值
改变指针变量指向的值
通过new()函数创建指针变量
数组
定义数组
下标访问
遍历数组:for
for遍历数组:for range
for range数组比较
必须保证数组类型长度相同,才能进行数组比较:
多维数组
切片

切片是对数组连续片段的引用
这个片段可以是整个数组,也可以是指定起始位置的子集
切片内部主要包括三个部分
data,指向切片所在数组的开始元素位置的指针
len,切片的长度
cap,切片的容量(底层数组的长度)
定义切片:从已有数组生成
从开始切到结尾
从指定位置切到结尾
从开始切刀指定位置
重置切片:空切片
定义切片:直接定义
切片声明与数组声明很像,只不过切片的声明没有长度;这种方式声明切片与make()函数效果一致,底层都会创建一个不可访问的数组
定义切片:使用make()函数构造切片
切片容量:cap()
cap()切片长度:len()
len()添加元素:append()
在使用 append() 函数为切片动态添加元素时,如果空间不足以容纳足够多的元素,切片就会进行“扩容”,此时新切片的长度会发生改变
切片在扩容时,容量的扩展规律是按容量的 2 倍数进行扩充,也就是扩容因子为2
复制:copy()
复制需要保证切片类型一致
删除元素
切片的删除实际上仍然是根据当前切片切割,比如删除头部元素:
删除中间位置:
删除尾部元素:
遍历切片:range
多维切片
映射
map,键值对映射结构,一种元素对(pair)的无序集合,pair 对应一个 key(索引)和一个 value(值),所以这个结构也称为关联数组或字典,这是一种能够快速寻找值的理想结构,给定 key,就可以迅速找到对应的 value
key不可以重复
key的类型不能是:
slice、map、functionvalue的不做限制
定义map
遍历map: range
添加/更新键值对
删除键值对: delete()
清空map
go没有提供清空map的方法,有两种方法可以清空map:
遍历调用
delete()给变量重新赋予一个新创建的map
结构体
结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正地分配内存。
定义结构体
type用于自定义类型,定义type可以对结构体进行复用
同类型变量可将字段放在一行
空结构体,没有意义
字段类型不受限制
结构体的字段类型不受限制,可以是基本类型,也可以是复合类型,比如函数等:
实例化结构体
基本实例化形式
实例化指针类型结构体(常用)
取地址符的实例化(常用)
对结构体进行&取地址操作时,视为对该类型进行一次 new 的实例化操作
初始化结构体
键值类型初始化
多值列表初始化
字段顺序要保持一致
所有字段必须要初始化
匿名结构体的初始化
管道
参见:并发编程/channel
函数
接口
参照:面向对象/接口
类型定义
无论是类型还是类型别名,都可以为他们指定方法
类型别名
类型别名是Go1.9版本添加的新功能,主要用于解决代码升级、迁移中存在的类型兼容性问题。再重构、升级代码时,经常会遇到变量名称变更,C/C++选择使用宏快速定义一段新的代码,而Golang则使用类型别名:
定义类型别名:
无论是类型还是类型别名,都可以为他们指定方法
最后更新于
这有帮助吗?