你可以寫一個簡單的語句,使切片的淺拷貝,
b := append([]T(nil), a...)
即相當於,
b := make([]T, len(a))
copy(b, a)
例如,
package main
import "fmt"
type T int
func main() {
a := []T{4, 2}
b := append([]T(nil), a...)
fmt.Println(&a[0], a, &b[0], b)
b[0] = 9
fmt.Println(&a[0], a, &b[0], b)
}
輸出:
0x10328000 [4 2] 0x10328020 [4 2]
0x10328000 [4 2] 0x10328020 [9 2]
附錄:
Common difficulties with reflection
如果人們新去的,他們不應該使用反射的。
-rob
即使對於專家來說,反射也是微妙的。它公開了一些細節,他們的理解依賴於瞭解語言如何工作以及在較小程度上如何實現語言的基本知識。即使對於有經驗的Go程序員來說,它也可能令人迷惑不解。對於最近 鑄造Gophers有更重要,更簡單的事情首先學習 。那些反思過早的人會迷惑自己對這些基本面的理解。最好保持在手臂的 長度,直到圖片的其餘部分清晰。
-Rob
這就是說,
package main
import (
"fmt"
"reflect"
)
func CopySlice(s interface{}) interface{} {
t, v := reflect.TypeOf(s), reflect.ValueOf(s)
c := reflect.MakeSlice(t, v.Len(), v.Len())
reflect.Copy(c, v)
return c.Interface()
}
type T int
func main() {
{
// append
a := []T{4, 2}
b := append([]T(nil), a...)
fmt.Println(&a[0], a, &b[0], b)
b[0] = 9
fmt.Println(&a[0], a, &b[0], b)
}
{
// make and copy
a := []T{4, 2}
b := make([]T, len(a))
copy(b, a)
fmt.Println(&a[0], a, &b[0], b)
b[0] = 9
fmt.Println(&a[0], a, &b[0], b)
}
{
// reflection
a := []T{4, 2}
b := CopySlice(a).([]T)
fmt.Println(&a[0], a, &b[0], b)
b[0] = 9
fmt.Println(&a[0], a, &b[0], b)
}
}
輸出:
0xc20800a200 [4 2] 0xc20800a210 [4 2]
0xc20800a200 [4 2] 0xc20800a210 [9 2]
0xc20800a290 [4 2] 0xc20800a2a0 [4 2]
0xc20800a290 [4 2] 0xc20800a2a0 [9 2]
0xc20800a310 [4 2] 0xc20800a320 [4 2]
0xc20800a310 [4 2] 0xc20800a320 [9 2]
因此,本質上,您將'a'的元素添加到分配給'b'的新陣列的新空片段中,對嗎? – Kaiged 2014-10-17 20:58:03
'append'方法與'make' /'copy'方法一樣嗎? – Kaiged 2014-10-17 21:17:24
@Kaiged:對「無」片段的附加轉換爲「make」和「copy」。看到我修改後的答案。 – peterSO 2014-10-17 21:19:40