go语言基础踩坑合集(一)

52 阅读2分钟

go语言切片对go指针的使用的影响

c指针和go指针在大体上是一致的,且若按照C的方式写go的指针也完全没有问题,但是在做一个算法题 23. 合并 K 个升序链表的时候发现了一个奇怪的现象。
简而言之就是在使用pop,push对数组进行增加和删去对象时,必须使用指针,而用swap交换数组对象则不用。 写的测试程序如下

import "fmt"

// 总结 go中所有切片引用的底层数组相同,所以对切片p进行切片q,并对q进行修改也会影响到p,swap同理
func main() {
   p := []int{1, 2, 3}
   swap(p)
   fmt.Println(p)
   swap1(&p)
   fmt.Println(p)
   q := p[0:1]
   q[0] = 0
   fmt.Println(p)
   fmt.Println(q)
}
func swap(p []int) {
   p[0], p[1] = p[1], p[0]
   p = append(p, 4)
}
func swap1(p *[]int) {
   (*p)[0], (*p)[1] = (*p)[1], (*p)[0]
   *p = append(*p, 5)
}

输出结果如下
[2 1 3] \\交换成功了,但是append失败了
[1 2 3 5]
[0 2 3 5]  可以看到q修改导致了p修改,因为二者共用同一个底层数组
[0]
  • 在Go语言中,切片是对底层数组的引用,而不是对数据本身的拷贝。这就意味着对切片的修改会直接影响底层数组以及所有引用该底层数组的切片。这也是为什么q修改会导致p修改

    在你的代码中,swap函数和swap1函数都交换了切片中的前两个元素,这将影响切片底层数组中的元素顺序,因此无论是通过值传递还是指针传递,这两个函数都会对外部切片产生影响。所以,无论是swap还是swap1,都会影响外部切片的内容。

    至于append操作,它会影响切片的长度和容量,以及可能触发底层数组的重新分配。当使用值传递传递切片时,append操作只会在函数内部的拷贝上进行操作,而不会影响外部的切片,因为函数内部的拷贝和外部切片引用的是不同的底层数组。但是,当使用指针传递传递切片时,append操作会影响外部切片,因为函数内部的指针和外部切片引用相同的底层数组。

    所以,无论是交换操作还是append操作,使用指针传递的情况下都会影响外部切片,而使用值传递的情况下则只会影响函数内部的拷贝

应该是很基础的问题。

A959A7B612035ABFFB13EF2EC4BE03A8.png