您可以编写一个简单的语句来制作切片的浅表副本,
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)
}
Output:
0x10328000 [4 2] 0x10328020 [4 2]
0x10328000 [4 2] 0x10328020 [9 2]
附录:
反思的常见困难 https://groups.google.com/d/topic/golang-nuts/abpF-Ykd0Z0/discussion
如果人们是 Go 新手,他们根本不应该使用反射。
-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)
}
}
Output:
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]