go语言之slice深度理解

创建空切片

var s []int
fmt.Println(s == nil)   // 输出 true
fmt.Println(len(s),cap(s))   // 输出:0 0
//声明了一个nil切片s,其实,切片的零值就是nil
//因为切片就是一个数组的引用。切片的类型在初始化时已经确认,就是[]Type,
//上面的代码就声明了[]int类型的nil切片s。nil切片的指向底层数组的指针为nil

------------------------------------------ 创建 空切片 ----------------------------------------

// 1、使用 make 创建空的整型切片
s := make([]int, 0)
// 2、使用切片字面量创建空的整型切片
s := []int{}
fmt.Println(s)   // 输出:[]
fmt.Println(len(s),cap(s))   // 输出:0 0
//说明切片底层的数组大小为0,是一个空数组(没有分配任何的存储空间)

------------------------------------------ 切片 copy -------------------------------------------

//内置函数copy,可以讲一个切片复制到另一个切片。函数原型:
//dst是目标切片,src是源切片,函数返回两者长度的最小值。
func copy(dst, src []Type) int
var s1 []int
s2 := []int{1, 2, 3}
s3 := []int{4, 5, 6, 7}
s4 := []int{1, 2, 3}
// 1、
n1 := copy(s1, s2)
fmt.Printf("n1=%d, s1=%v, s2=%v\n", n1, s1, s2)
fmt.Println("s1 == nil", s1 == nil)
//输出:
n1=0, s1=[], s2=[1 2 3]
s1 == nil true
//因为s1是nil切片,执行完copy操作之后,s1依然还是nil,空切片 make的才能用
这和append()是不同的
var s1 []int
s2 := []int{1, 2, 3}
s1 = append(s1, s2...)
fmt.Println(s1)   // 输出:[1 2 3]
// 2、
n2 := copy(s2, s3)
fmt.Printf("n2=%d, s2=%v, s3=%v\n", n2, s2, s3)
//输出:n2=3, s2=[4 5 6], s3=[4 5 6 7]
// 3、
n3 := copy(s3, s4)
fmt.Printf("n3=%d, s3=%v, s4=%v\n", n3, s3, s4)
//输出:n3=3, s3=[1 2 3 7], s4=[1 2 3]
//上面代码显示copy只会复制,不会追加。

---------------------------------------------- 切片 append ---------------------------------------

删除索引为2 的元素
var str = []int{1, 2, 3, 4, 5, 6}
//切片截取:前包含后不包含
fmt.Println(str[:2])  //索引默认从0开始,不包含2
fmt.Println(str[3:5]) //索引从3(包含)开始,不包含5
fmt.Println(str[3:])  //索引从3(包含)开始,到最后
str = append(str[:2], str[3:]...)
fmt.Println(str)
//输出:
[1 2]
[4 5]
[4 5 6]
[1 2 4 5 6]

-------------------------------------- 函数间传递 切片 ----------------------------------------

切片在函数间以值的方式传递。由于切片的尺寸很小(
在 64 位架构的机器上,一个切片需要 24 字节的内存:
指针字段、长度和容量字段各需要 8 字节),
在函数间复制和传递切片成本也很低。切片发生复制时,底层数组不会被复制,
数组大小也不会有影响
func main() {
 s := []int{0, 1, 2, 3, 4, 5}
 fmt.Printf("%p\n", &s)
 modify(s)
 fmt.Println(s)
}
func modify(s []int) {
 fmt.Printf("%p\n", &s)
 s[1] = 10
}
//输出:
0xc000086020
0xc000086040
[0 10 2 3 4 5]
原切片地址和传递之后的切片的地址是不一样的,说明发生了复制;
在函数modify中修改了切片一个值,原切片的值也随之改变了,
说明这两个切片是共享底层数组的。

在函数间传递切片非常高效,而且不需要传递指针和处理复杂的语法,只需要复制切片,
按自己的业务修改数据,最后传递回一个新的切片副本即可,
这也是为什么函数间使用切片传参,而不是数组传参的原因
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值