在GoLang中,slice2:= slice1等于slice2:= slice1 [:]吗?
Do the two following lines of code do the same thing in GoLang? What I want to do is to copy a slice into another one:
slice1 := make([]int, 5)
slice2 := slice1 #line1
slice2 := slice1[:] #line2
I run this code to test the behaviour, but apparently they both work int the same way:
func main() {
s1 := make([]int, 5, 5)
s1[2] = 33
fmt.Printf(“s1: %v: address of slice %p
“, s1, &s1)
s2 := s1[:]
s2[1] = 5
fmt.Printf(“s2: %v: address of slice %p
“, s2, &s2)
s3 := s1
s3[0] = 23
fmt.Printf(“s3: %v: address of slice %p
“,s3, &s3)
fmt.Printf(“s2: %v: address of slice %p
“, s2, &s2)
fmt.Printf(“s1: %v: address of slice %p
“, s1, &s1)
}
The output is:
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
So the memory addresses of the slices (s1, s2, s3) are different but the pointers to the arrays contained into them, point to the same memory address.
I’m wondering if there is something that changes between this two ways, or if there is a sort of convention that says what’s better to use.
The result is the same.
One thing you didn’t check is the capacity, another property of slices. So let’s check that one too:
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))
Output (try it on the Go Playground):
2 4
2 4
2 4
Basically the slice expression s[:] means to slice the slice, and use 0 as the lower index, and len(s) as the upper, and cap(s) as the capacity. So the result will be a slice identical to s.
For readability, just copy the slice header: s2 := s.
Also note that if s would be nil, both copying it and slicing it will also result in nil slices:
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)
Output of the above is (try it on the Go Playground):
0 0 true
0 0 true
0 0 true
So there is absolutely no difference in the result. A compiler implementation may or may not mimic the s2 := s statement when you write s2 := s[:], so the latter may be slower. But again, there is no reason not to simply copy it.