关于后端:Go-语言为什么建议-append-追加新元素使用原切片变量接收返回值

2次阅读

共计 1319 个字符,预计需要花费 4 分钟才能阅读完成。

介绍

在 Go 语言中,切片类型比拟罕用,将新元素追加到切片也比拟常见,因而 Go 语言提供一个内置函数 append,该函数能够十分不便实现此性能。

尽管 Go 语言内置函数 append 应用十分不便,然而使用不当会不小心掉入一些“坑”。

本文咱们介绍一下 Go 语言为什么倡议 append 追加新元素应用原切片变量接管返回值?

append 的“坑”

咱们先看一段示例代码:

func main() {a := make([]int, 0, 5)
 a = append(a, 1)
 b := append(a, 2)
 c := append(a, 3)
 fmt.Printf("v=%v || p=%p\n", a, &a) // v=[1] || p=0xc00000c060
 fmt.Printf("v=%v || p=%p\n", b, &b) // v=[1 3] || p=0xc00000c080
 fmt.Printf("v=%v || p=%p\n", c, &c) // v=[1 3] || p=0xc00000c0a0
}
  1. 浏览下面这段代码,咱们定义一个长度为 0,容量为 5 的 int 类型的切片 a。
  2. 首先,咱们应用 Go 语言内置函数 append 追加一个元素 1 到切片 a 中。
  3. 而后,咱们应用 Go 语言内置函数 append 追加一个元素 2 到切片 a 中。
  4. 最初,咱们应用 Go 语言内置函数 append 追加一个元素 3 到切片 a 中。

然而,咱们在输入后果中发现,b 的输入后果不是 [1 2],c 的输入后果不是 [1 2 3],b 和 c 的理论输入后果雷同,都是 [1 3]。为什么呢?咱们接着往下看 Part 03 的内容。

append 的原理

Go 语言内置函数 append 第一个入参是切片类型的变量,而切片自身是一个 struct 构造,参数传递时会产生值拷贝。

Go 语言 slice 源码如下:

type slice struct {
 array unsafe.Pointer
 len   int
 cap   int
}

因为 Go 语言内置函数 append 参数是值传递,所以 append 函数在追加新元素到切片时,append 会生成一个新切片,并且将原切片的值拷贝到新切片。

  1. 在 Part 02 示例代码中,咱们三次应用 append 参数追加新元素到切片 a 的操作,接管返回值的变量都不同。
  2. 第二次操作时,因为 append 生成一个新切片,将原切片 a 的值拷贝到新切片,并且将新元素在原切片 a[len(a)] 长度的地位开始追加,应用变量 b 接管 append 返回值 [1 2],所以变量 b 的值是 [1 2]。
  3. 第三次操作时,同样 append 生成一个新切片,将原切片 a 的值拷贝到新切片,并且将新元素在原切片 a[len(a)] 长度的地位开始追加,应用变量 c 接管 append 返回值 [1 3],所以变量 c 的值是 [1 3]。
  4. 然而,因为三个切片的底层数组雷同,Go 内置函数 append 会在原切片长度的地位开始追加新元素,所以第三次操作时,把第二次操作时失去的变量 b 的最初一个元素笼罩了。

浏览到这里,置信聪慧的读者敌人们曾经明确 Part 02 示例代码为什么理论输入后果和料想的输入后果不同了吧。

总结

本文咱们介绍 Go 语言中应用内置函数 append 追加新元素的一个“坑”,倡议读者敌人们应用原切片变量接管返回值。

| 原文 https://mp.weixin.qq.com/s/jG…

本文由 mdnice 多平台公布

正文完
 0