草庐IT

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

coder 2023-06-27 原文

下面两行代码在 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/

有关go - 是 slice2 := slice1 equal to slice2 := slice1[:] in GoLang?的更多相关文章

  1. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  2. ruby-on-rails - 用于 Ruby 的 vim 中的全局 "Go to definition"? - 2

    自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby​​编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例

  3. ruby - 为什么 Array#slice 和 Array#slice!表现不同? - 2

    我不明白为什么在Ruby中,Array#slice和Array#slice!的行为与Array#sort和Array#sort!(一个返回新数组的结果,另一个处理当前对象)。使用sort第一个(没有爆炸),返回当前数组的排序副本,并且sort!对当前数组进行排序。slice,返回指定范围的数组,slice!从当前对象删除指定范围。Array#slice!的行为为何如此,而不是使当前对象成为具有指定范围的数组?例子:a=[0,1,2,3,4,5,6,7,8,9]b=a.slice(2,2)puts"slice:"puts"a="+a.inspectputs"b="+b.inspectb=

  4. ruby - Rubys 的 each_slice 的 Scala 版本? - 2

    Scala有Rubys的版本吗each_slice来自Array类? 最佳答案 Scala2.8有grouped将数据分成大小为n的block(可用于实现each_slice功能):scala>vala=Array(1,2,3,4,5,6)a:Array[Int]=Array(1,2,3,4,5,6)scala>a.grouped(2).foreach(i=>println(i.reduceLeft(_+_)))3711据我所知,在2.7.x中没有任何东西可以开箱即用,但是从take(n)和drop(n)来自RandomAccess

  5. ruby-on-rails - Rails 上的 ruby : How to have multiple submit buttons going to different methods (maybe with with_action? ) - 2

    这个问题在这里已经有了答案:HowdoIcreatemultiplesubmitbuttonsforthesameforminRails?(7个答案)关闭9年前。所以..'save'%>'library'%>然后在我的Controller中:with_actiondo|a|a.savedoenda.librarydoendend问题是只有一个操作被调用...两个submit_tags调用相同的操作...知道为什么吗?或者我如何获得两个按钮以将表单提交给两种不同的方法?

  6. ruby - Array#slice 的重叠等效项 - 2

    这个问题在这里已经有了答案:Rubyarrayaccess2consecutive(chained)elementsatatime(4个答案)关闭3年前。给定这个Ruby数组:[1,2,3,4,5]像这样迭代它的最简单方法是什么?[[1,2],[2,3],[3,4],[4,5]]还是这个?[[1,2,3],[2,3,4],[3,4,5]]

  7. DiFi: A Go-as-You-Pay Wi-Fi Access System 精读笔记(三) - 2

    IV.SYSTEMIMPLEMENTATIONWeadoptmodulardesignfollowingtheintegrationofblockchain.Itbringsmoreflexibilitybyseparatingtheimplementationofdifferentfunctionalities,sowecouldleveragetheadvantagesoftheblockchain-basedsmartcontractwhilereducingoverhead.Figure3illustrateshowdifferentmodulesareinvolvedintheint

  8. go-templates - 如何根据表达式有条件地在 Go 模板中设置变量,如果不使用 if 语句包装可能会导致错误 - 2

    问题我该如何做这样的事情:{{$use_ssl:=(ne$.Env.CERT_NAME"")}}其中$.Env.CERT_NAME可能为零/未定义。如果它是零,它给出这个错误:at:errorcallingne:invalidtypeforcomparison注意:我无法控制传递给Go模板的对象,因此必须完全在模板本身内解决这个问题。我尝试过的我试图通过首先检查它是否为非空来变通:{{$use_ssl:=(($.Env.CERT_NAME)&&(ne$.Env.CERT_NAME""))}}但它给出了这个错误:unexpected"&"inoperand所以我切换到这个,这在语法上是允

  9. Go time与string的相爱相杀 - 2

    time包与string包可以说是在Go语言的开发中常用的两个包实际开发过程中(例如web开发)经常会遇到time类型与string类型的交互,计算比较等场景首先来了解GO语言里非常浪漫的一个点,即2006-01-0215:04:05,GO语言诞生的时间,通常用来做时间的格式化time转stringt:=time.Now()//当前时间timeLayoutStr:="2006-01-0215:04:05"t.Format(timeLayoutStr)//返回值为string,可以用一个值来接收它上述例子中,将time类型t转换为string类型,并格式化为年-月-日时-分-秒,这里的格式化是可

  10. ruby - 为什么 array.slice 对 (length, n) 的行为不同 - 2

    如果我有一个数组a:a[a.length]返回nil。好。a[a.length,x]返回[]。好。a[a.length+x,y]返回nil。与2不一致。虽然此行为是documented,看起来很奇怪。谁能解释一下这种设计背后的原因? 最佳答案 考虑一下a=[0,1,2,3]#=>[0,1,2,3]a[0,10]#=>[0,1,2,3]a[1,10]#=>[1,2,3]a[2,10]#=>[2,3]a[3,10]#=>[3]a[4,10]#=>[]a[5,10]#=>nil所以a[4,10]是3之间的切片和数组的末尾[]哪里a[4]和

随机推荐