Go语言学习笔记——数组、slice

数组

数组是具有固定长度且拥有零个或多个相同数据类型元素的序列

由于数组固定长度,因此用的比较少,slice的长度是动态的,用的更多

初始化

  • 默认初始化为元素类型的零值
var a [3]int
  • 省略号出现在数组长度的位置,那么数组的长度由初始化的元素个数决定
q := [...]int{1, 2, 3}
fmt.Println("%T\n", q) // "[3]int"
  • 通过指定索引初始化
// 定义了一个拥有100个元素的数组r,除了最后一个元素值是-1外,该数组中的其他元素值都是0
r := [...]int{99: -1}

比较

如果一个数组的元素是可比较的,那么这个数组也是可比较的,即可以用==!=操作符比较

数组的长度是数组类型的一部分,因此[3]int[4]int是两种不同的数组类型

数组作为函数参数

Go语言中与C\C++中一个很大不同是,数组是值传递,而不是引用传递

就是调用一个函数时,每个传入的参数都会创建一个副本,函数内改变的数副本,而不是原始数据

当然也可以用数组指针

slice

slice表示一个拥有相同类型的可变长度的序列

slice有三个属性:指针、长度和容量

  • 指针指向数组的第一个可以从slice中访问的元素,这个元素不一定是数组的第一个元素
  • 长度是指slice中的元素个数,它不能超过slice的容量
  • 容量的大小通常是从slice的起始元素到底层数组的最后一个元素间元素的个数
    Go的内置函数lencap用来返回slice的长度和容量

一个底层数组可以对应多个slice,这些slice可以引用数组的任何位置

slice作为函数参数

因为slice包含了指向数组元素的指针,所以一个slice传递给函数的时候,可以在函数内部修改底层数组的元素

就是创建一个slice等于为数组创建了一个别名

比较

与数组不同的是,slice无法做比较

标准库中有bytes.Equal来比较两个字节slice([]byte),但是对于其他类型的slice就需要自己写函数比较

slice唯一允许的比较操作是和nil做比较

slice类型的零值是nil,值为nil的slice没有对应的底层数组,长度和容量都是零

但是也有非nil的slice长度和容量是零

因此如果要检查一个slice是否为空,使用len(s) == 0,而不是s == nil

make

内置函数make可以创建一个具有指定元素类型、长度和容量的slice,其中容量参数可以省略,在这种情况下,slice的长度和容量相等

make([]T, len)
make([]T, len, cap)

其实make创建了一个无名数组并返回了它的一个slice,这个数组仅可以通过这个slice来访问

append函数

内置函数append用来将元素追加到slice的后面

通常情况下,我们不清楚一次append调用会不会导致一次新的内存分配,
所以我们不能假设原始的slice和调用append后的结果slice指向同一个底层数组,
同样我们也无法假设旧slice对元素的操作会或者不会影响新的slice元素

所以,通常我们将append的调用结果,再次复制给传入append函数的slice

runes = append(runes, r)

不仅仅是调用append函数的情况下需要更新slice变量,对于任何函数只要有可能改变slice的长度或者容量,
抑或是使得slice指向不同的底层数组,都需要更新slice变量

总结

  • 数组是具有固定长度且拥有零个或多个相同数据类型元素的序列
  • 数组是值传递,而不是引用传递
  • slice表示一个拥有相同类型的可变长度的序列
  • 与数组不同的是,slice无法做比较
  • slice类型的零值是nil,值为nil的slice没有对应的底层数组,长度和容量都是零
  • 如果要检查一个slice是否为空,使用len(s) == 0,而不是s == nil
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值