Golang复合类型

本文详细介绍了Golang中的复合类型,包括数组、Slice、Map和Struct。数组在Go中使用较少,Slice作为变长序列更常用,其初始化、操作、切片和复制等特性进行了深入探讨。Map提供了key-value存储,支持基本操作如初始化、添加和删除元素。Struct用于聚合数据,讨论了定义、声明、结构体指针和匿名成员。还提到了Json的编码和解码过程。
摘要由CSDN通过智能技术生成

前言

上文 Golang 基本类型 中我们介绍了golang 基本类型的常见用法,本文将介绍 golang 中的复合数据类型,常用的复合数据类型有 array 数组,slice 切片,map 字典 和 struct 四种。

数组

数组是一个由固定长度特定类型元素组成的序列,由于长度固定,在实际业务场景下使用较为不便,因此在 go 中很少直接使用。

数组的长度是数组类型的一个组成部分,因此 [3]int 和 [4]int 是两种不同的数组类型。数组的长度必须是常量表达式,因为数组的长度需要在编译阶段确定。

和大多数语言一样,go 的数组下表也是从 [0] 开始,到 [len - 1] 结束

var a [3]int
var q [3]int = [3]int{
   1,2,3}   // 1,2,3
var r [3]int = [3]int{
   1,2}     // 1,2,0

a[0] = 1
a[1] = 2
a[2] = 3

也可以使用 “…” 来声明数组,如果在数组的长度位置出现的是“…”省略号,则表示数组的长度是根据初始化值的个数来计算,因此,上面 q 数组的定义可以简化为

q := [...]int{
   1,2,3}
fmt.Println(reflect.TypeOf(q))  // 输出 [3]int

对于较大的数组,可以指定一个索引和对应值列表的方式初始化,如下,定义了一个含有100个元素的数组r,索引为 13 的位置值为 21,最后一个元素被初始化为 -1,其它元素都是用 0 初始化。

r := [...]int{
   13: 21, 99: -1}

Slice

Slice(切片)代表变长的序列,序列中每个元素都有相同的类型

go 的 slice 底层是由数组实现的,一个slice由三个部分构成:指针、长度和容量。创建 slice 时,指针指向第一个slice元素对应的底层数组元素的地址,长度对应slice中元素的数目,容量表示创建数组时分配空间的初始大小,长度不能超过容量,容量一般是从slice的开始位置到底层数据的结尾位置。

和数组不同的是,slice 之间不能使用 == 互相比较,slice 唯一合法的比较操作是和nil比较, 但是通常更推荐使用 len(s) == 0来判断,而不是 s == nil,否则对 []int{} 这种形式的 slice 判断会出现问题,可以参考如下代码。

var s []int 	// len(s) == 0, s == nil
s = []int(nil)  // len(s) == 0, s == nil
s = []int{
   }     // len(s) == 0, s != nil

slice 基本操作

初始化

使用 make([]Type, len, cap) 初始化 slice, cap 参数可以缺省, 缺省时默认 cap 等于 len

sl_null := []int{
   } 	// 创建空slice
sl0 := make([]int, 0, 3)  // 创建 cap 为 3 的空 slice []
sl1 := make([]int, 0)  // 创建 []
sl2 := make([]int, 3)  // 创建 [0,0,0]

// 创建有初始内容的 slice
sl4 := []int{
   1,2,3}    // 类型为 []int
// 注意区分 slice 和 数组的初始化
// 数组的初始化为 s := [...]{1,2,3}, 类型为 [3]int

在 slice 末尾添加元素

添加元素时,如果添加完成后 len 大于当前 cap, slice 会进行扩容, 每次扩容 cap 的大小会翻一倍

sl3 = append(sl3, 4)   // 添加单个元素
sl3 = append(sl3, 5, 6, 7)  // 添加多个元素

sl4 := []int{
   8, 9, 10}
sl3 = append(sl3, sl4...)   // 将 sl4 展开,把所有元素添加到 sl3 末尾
// 修改 sl3 不会改变 sl4 的元素

获取 slice 长度和容量

内置的 lencap 函数分别返回slice的长度和容量。

len_sl3 = len(sl3)   // int
cap_sl3 = cap(sl3)   // int

查看某元素是否在 slice 里

没有内置函数,需要自己遍历实现, 对 slice 遍历时取到两个值,第一个为 slice 的下标,第二个为下标对应的值。

for _, num := rang num_slice {
   
	if num == target {
   
		// ...
	}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值