iswbm / GolangCodingTime

Go编程时光,一个零基础入门 Golang 的教程

Home Page:http://golang.iswbm.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

c01/c01_05

utterances-bot opened this issue · comments

1.5 数据类型:数组与切片 — Go编程时光 1.0.0 documentation

https://golang.iswbm.com/c01/c01_05.html

因为切片类型为指向类型,实际指向的是数组

关于切片的说法的错误,

        sliceArr := [...]int{1, 2, 3}
	myArr := []int{}
	sliceArr = append(sliceArr, 1, 2, 3)

这里面使用[...]int{1,2,3) 创建出来根本不是slice 类型, 可以自己测试一下, slice的创建语法一般是下面2种

//  创建一个数组
myArr := [...]int{1,2,3}
// 将数组转换成slice 
slice := myArr[:]
// 手动创建一个slice
slice1 := []int {1,23}

cap 容量为4

commented
// 切片的好处还包括长度可变,解包后容量的变化不太明白
sliceN := []int{1}
fmt.Printf("sliceN(%d) 的长度为:%d,容量为:%d\n", sliceN, len(sliceN), cap(sliceN))
sliceN = append(sliceN, 2)
// 长度和容量自动变长
fmt.Printf("sliceN(%d) 的长度为:%d,容量为:%d\n", sliceN, len(sliceN), cap(sliceN))
// 可追加多个元素
sliceN = append(sliceN, 3, 4)
fmt.Printf("sliceN(%d) 的长度为:%d,容量为:%d\n", sliceN, len(sliceN), cap(sliceN))
// 可追加一个切片, ... 表示解包,不能省略
sliceN = append(sliceN, []int{7, 8}...)
fmt.Printf("sliceN(%d) 的长度为:%d,容量为:%d\n", sliceN, len(sliceN), cap(sliceN))
// 在第一个位置插入元素,以第一个元素为主体,后面的元素被解包
sliceN = append([]int{0}, sliceN...)
fmt.Printf("sliceN(%d) 的长度为:%d,容量为:%d\n", sliceN, len(sliceN), cap(sliceN))
// 在中间插入一个切片(两个元素)
sliceN = append(sliceN[:5], append([]int{5, 6}, sliceN[5:]...)...)
fmt.Printf("sliceN(%d) 的长度为:%d,容量为:%d\n", sliceN, len(sliceN), cap(sliceN))

请问容量是怎么被计算的?是不是按2^n增加?

sliceN([1]) 的长度为:1,容量为:1                 
sliceN([1 2]) 的长度为:2,容量为:2               
sliceN([1 2 3 4]) 的长度为:4,容量为:4           
sliceN([1 2 3 4 7 8]) 的长度为:6,容量为:8       
sliceN([0 1 2 3 4 7 8]) 的长度为:7,容量为:8     
sliceN([0 1 2 3 4 5 6 7 8]) 的长度为:9,容量为:16
commented

切片里面是指针、长度、容量,由于容量是4,所以访问第四个元素不会报错,因为是指向数组第四位的指针,所以第四个元素的值是8

slice类型是数组的一个引用,数组arr的地址0x83029,那么slice的数据结构是[ ptr | len| cap],ptr就是指向数组arr的,就是一个指针,即存放了地址0x83029,len存放了slice的长度,cap存放了slice的容量,但是这个容量是不可能超过arr的len的,所以这样看来slice是一个引用,存放的数据是在arr中,修改slice的数据,对应修改了数组的内容,所以
这个思考题,len是2,cap是4,那么它就可以通过ptr指针访问到arr后面的第四个元素。
大家明白了嘛?宝贝们,我是你们的程序员小袁