gpt4 book ai didi

go - 是 slice2 := slice1 equal to slice2 := slice1[:] in GoLang?

转载 作者:IT王子 更新时间:2023-10-29 00:57:22 24 4
gpt4 key购买 nike

下面两行代码在 Go 语言中做同样的事情吗?我想要做的是将一个 slice 复制到另一个 slice 中:

slice1 := make([]int, 5)
slice2 := slice1 #line1
slice2 := slice1[:] #line2

我运行这段代码来测试行为,但显然它们都以相同的方式工作:

func main() {
s1 := make([]int, 5, 5)
s1[2] = 33
fmt.Printf("s1: %v: address of slice %p\n", s1, &s1)
s2 := s1[:]
s2[1] = 5
fmt.Printf("s2: %v: address of slice %p\n", s2, &s2)
s3 := s1
s3[0] = 23
fmt.Printf("s3: %v: address of slice %p\n",s3, &s3)
fmt.Printf("s2: %v: address of slice %p\n", s2, &s2)
fmt.Printf("s1: %v: address of slice %p\n", s1, &s1)
}

输出是:

s1: [0 0 33 0 0]: address of slice 0x40c0e0
s2: [0 5 33 0 0]: address of slice 0x40c100
s3: [23 5 33 0 0]: address of slice 0x40c120
s2: [23 5 33 0 0]: address of slice 0x40c100
s1: [23 5 33 0 0]: address of slice 0x40c0e0

因此 slice (s1、s2、s3)的内存地址不同,但指向包含在其中的数组的指针指向相同的内存地址。

我想知道这两种方式之间是否有什么变化,或者是否有某种约定说明哪种方式更好用。

最佳答案

结果是一样的。

您没有检查的一件事是容量,这是 slice 的另一个属性。因此,让我们也检查一下:

s := make([]int, 2, 4)
s2 := s
s3 := s[:]

fmt.Println(len(s), cap(s))
fmt.Println(len(s2), cap(s2))
fmt.Println(len(s3), cap(s3))

输出(在 Go Playground 上尝试):

2 4
2 4
2 4

基本上是 slice expression s[:]表示对slice进行 slice ,下标为0,上标为len(s),上标为cap(s) 作为容量。所以结果将是一个与 s 相同的 slice 。

为了便于阅读,只需复制 slice header :s2 := s

另请注意,如果 snil,则复制它和对其进行 slice 也会导致 nil slice :

var s []int
s2 := s
s3 := s[:]

fmt.Println(len(s), cap(s), s == nil)
fmt.Println(len(s2), cap(s2), s2 == nil)
fmt.Println(len(s3), cap(s3), s3 == nil)

上面的输出是(在 Go Playground 上尝试):

0 0 true
0 0 true
0 0 true

所以结果绝对没有区别。当您编写 s2 := s[:] 时,编译器实现可能会或可能不会模仿 s2 := s 语句,因此后者可能慢一点。但同样,没有理由不简单地复制它。

关于go - 是 slice2 := slice1 equal to slice2 := slice1[:] in GoLang?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53499797/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com