关于slice更详细的理解
老师讲解的时候整体速度比较快,我也是初学者,在这里简单的写点关于slice和数组的个人理解,比较浅显,希望与大家一同进步。
var sli_1 []int
fmt.Printf("len=%d cap=%d slice=%v\n", len(sli_1), cap(sli_1), sli_1)
执行上述代码我们得到的结果是len=0 cap=0 slice=[],此时通过声明创建了一个空的slice,此时长度为0,容量为0;
var sli_2 = []int{}
fmt.Printf("len=%d cap=%d slice=%v\n", len(sli_2), cap(sli_2), sli_2)
执行上述代码我们得到的结果同样是len=0 cap=0 slice=[],与第一种方式相比语法不同。
var sli_3 = []int{1, 2, 3, 4, 5}
fmt.Printf("len=%d cap=%d slice=%v\n", len(sli_3), cap(sli_3), sli_3)
当我们创建一个包含5个int类型的slice时,得到如下结果,len=5 cap=5 slice=[1 2 3 4 5],切片的长度是5,容量仍然是5.
var sli_5 []int = make([]int, 5, 8)
fmt.Printf("len=%d cap=%d slice=%v\n", len(sli_5), cap(sli_5), sli_5)
当我们使用make创建一个数组时,参数设置为5,8得到如下结果len=5 cap=8 slice=[0 0 0 0 0];此时slice的结果是5个0,长度也是5,但容量是8,关于如何理解容量和slice长度的不相同的问题,切片slice可以看作是对数组的一个操作,涉及两个变量元素可操作长度len和可扩容长度cap。要想突破slice的扩容cap限制进行无限扩容就需要使用append()函数进行操作。如果append追加的元素后slice的总长度不超过底层数组的总长度,那么slice引用的地址不会发生改变。这里尝试用如下代码进行测试:
sli := []int{4, 5, 6}
sli1 = append(sli, 7)
sli2 = append(sli, 8)
我们创建一个包含4,5,6的slice,分别对它追加两次数据,观察他的长度和容量,我得到了下面的结果
- len=3 cap=3 slice=[4 5 6]
- len=4 cap=6 slice=[4 5 6 7]
- len=5 cap=6 slice=[4 5 6 7 8]
当一个slice容量不够的时候继续对它进行追加,发现他的容量会先提升一倍,然后长度会增加一,容量够得话长度直接增加1。
关于slice还有个需要注意的地方,查阅资料发现由于多个slice共享同一个底层数组,所以当修改了某个slice中的元素时,其它包含该元素的slice也会随之改变,因为slice只是一个指向底层数组的指针,实际上修改的是底层数组的值,而底层数组是被共享的。
以上是目前作为初学者对与slcie基本功能和形式的了解,接下来还会继续在实战过程中加深理解。