为了账号安全,请及时绑定邮箱和手机立即绑定

slice2 := slice1 等于 GoLang 中的 slice2 := slice1[:]

slice2 := slice1 等于 GoLang 中的 slice2 := slice1[:]

Go
饮歌长啸 2023-05-15 09:50:33
下面两行代码在 Go 语言中做同样的事情吗?我想要做的是将一个切片复制到另一个切片中:slice1 := make([]int, 5)slice2 := slice1 #line1slice2 := 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 0x40c0e0s2: [0 5 33 0 0]: address of slice 0x40c100s3: [23 5 33 0 0]: address of slice 0x40c120s2: [23 5 33 0 0]: address of slice 0x40c100s1: [23 5 33 0 0]: address of slice 0x40c0e0因此,切片(s1、s2、s3)的内存地址不同,但指向包含在其中的数组的指针指向相同的内存地址。我想知道这两种方式之间是否有什么变化,或者是否有某种约定说明更好用。
查看完整描述

1 回答

?
紫衣仙女

TA贡献1839条经验 获得超15个赞

结果是一样的。

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

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 表达式 基本上s[:]意味着对切片进行切片,并使用 0 作为下索引,作为len(s)上索引,cap(s)作为容量。所以结果将是一个与 相同的切片s

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

另请注意,如果snil,复制它和切片它也会产生nil切片:

var s []ints2 := 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[:],因此后者可能会更慢。但同样,没有理由不简单地复制它。


查看完整回答
反对 回复 2023-05-15
  • 1 回答
  • 0 关注
  • 94 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信