首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >slice2 := slice1在GoLang中是否等于slice2 := slice1[:]?

slice2 := slice1在GoLang中是否等于slice2 := slice1[:]?
EN

Stack Overflow用户
提问于 2018-11-27 12:32:45
回答 1查看 138关注 0票数 3

在GoLang中,下面两行代码是否做了相同的事情?我想要做的是将一片复制到另一片:

代码语言:javascript
复制
slice1 := make([]int, 5)
slice2 := slice1 #line1
slice2 := slice1[:] #line2

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

代码语言:javascript
复制
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)
}

产出如下:

代码语言:javascript
复制
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

因此,片的内存地址(s1、s2、s3)是不同的,但是指向它们所包含的数组的指针指向相同的内存地址。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-27 12:43:50

结果是一样的。

您没有检查的一件事是片的容量,另一项属性。所以我们也来看看这个:

代码语言:javascript
复制
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))

输出(在围棋游乐场上尝试):

代码语言:javascript
复制
2 4
2 4
2 4

基本上,切片表达式 s[:]意味着切片,使用0作为较低的索引,使用len(s)作为上层,使用cap(s)作为容量。因此,结果将是一个与s相同的切片。

为了提高可读性,只需复制切片头:s2 := s

还请注意,如果snil,那么复制和切片它也会导致nil片:

代码语言:javascript
复制
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)

上面的输出是(在围棋游乐场上尝试一下):

代码语言:javascript
复制
0 0 true
0 0 true
0 0 true

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53499797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档