数组与slice区别
数组是固定长度的,不同长度的数组不是相同类型,初始化方式如下
t := [3]int{}
slice长度可变,实际上是一个指向相应底层对象的指针,初始化方式如下
t := make([]int, 0)ort := []int{}
对任意数组或slice切片得到的是slice,实际上是一个包含了长度和容量的指针,指向了其底层位置
func main() {t := [3]int{1,2,3}v := t[:]fmt.Printf("%v %T %p\n", t, t ,&t)fmt.Printf("%v %T %p\n", v, v, v)v[1] = 5fmt.Printf("%v %T %p\n", t, t, &t)}// result[1 2 3] [3]int 0xc0000ae078[1 2 3] []int 0xc0000ae078[1 5 3] [3]int 0xc0000ae078
append
对于append方法,如果其slice所对应的底层数组还有空间,则在原地append,否则会申请新的底层数组空间
func main() {t := [3]int{1,2,3}v := t[:2]fmt.Printf("%v %T %p\n", t, t ,&t)fmt.Printf("%v %T %p\n", v, v, v)v = append(v ,5)fmt.Printf("%v %T %p\n", t, t, &t)fmt.Printf("%v %T %p\n", v, v, v)fmt.Println("***************************")t = [3]int{1,2,3}v = t[:]fmt.Printf("%v %T %p\n", t, t ,&t)fmt.Printf("%v %T %p\n", v, v, v)v = append(v ,5)fmt.Printf("%v %T %p\n", t, t, &t)fmt.Printf("%v %T %p\n", v, v, v)}// result[1 2 3] [3]int 0xc0000ae078[1 2] []int 0xc0000ae078[1 2 5] [3]int 0xc0000ae078[1 2 5] []int 0xc0000ae078***************************[1 2 3] [3]int 0xc0000ae078[1 2 3] []int 0xc0000ae078[1 2 3] [3]int 0xc0000ae078[1 2 3 5] []int 0xc0000c0060
以上是我们所期望多append策略,但并不能保证append一定采用。内置的append采用更复杂的内存扩展策略。因此,通常我们并不知道append调用是否导致了内存的重新分配,因此我们也不能确认新的slice和原始的slice是否引用的是相同的底层数组空间。同样,我们不能确认在原先的slice上的操作是否会影响到新的slice。因此,通常是将append返回的结果直接赋值给输入的slice变量:
runes = append(runes, r)
参数传递
当传参时,数组与slice均是值传递,但slice其实包含3个值,分别是len、cap、和底层指针,所以实际传进去的是底层指针。
package mainimport ("fmt")func printAddressAndChangeValue1(t [3]int) {fmt.Printf("the address of array t in function when transmit a value is: %p\n", &t)t[1] = 1}func printAddressAndChangeValue2(p []int) {fmt.Printf("the address of array t in function when transmit a value is: %p\n", p)p[1] = 1}// 验证go数组是值传递还是地址传递func main() {t := [3]int{9,8,7}fmt.Printf("value of t: %v, type of t: %T\n" ,t, t)fmt.Printf("the address of array t out function is: %p\n", &t)printAddressAndChangeValue1(t)fmt.Printf("value of t: %v, type of t: %T\n" ,t, t)fmt.Println("************************")p := []int{9,8,7}fmt.Printf("value of t: %v, type of t: %T\n" ,p, p)fmt.Printf("the address of array t out function is: %p\n", p)printAddressAndChangeValue2(p)fmt.Printf("value of t: %v, type of t: %T\n" ,p, p)}// resultvalue of t: [9 8 7], type of t: [3]intthe address of array t out function is: 0xc000012120the address of array t in function when transmit a value is: 0xc000012168value of t: [9 8 7], type of t: [3]int************************value of t: [9 8 7], type of t: []intthe address of array t out function is: 0xc0000121b0the address of array t in function when transmit a value is: 0xc0000121b0value of t: [9 1 7], type of t: []intProcess finished with the exit code 0
