下面兩行代碼在 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
。
另請注意,如果s
是nil
,復制它和切片它也會產生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[:]
,因此后者可能會更慢。但同樣,沒有理由不簡單地復制它。
- 1 回答
- 0 關注
- 131 瀏覽
添加回答
舉報
0/150
提交
取消