3 回答
TA贡献1898条经验 获得超8个赞
你可以写一个简单的语句来制作一个切片的浅拷贝,
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]
附录:
反思的常见困难
如果人们是 Go 的新手,他们根本不应该使用反射。
-抢
即使对于专家来说,反思也是微妙的。它揭示了细节,其理解取决于了解语言如何工作的基本知识,在较小程度上,它是如何实现的。即使对于有经验的 Go 程序员来说,这也会令人困惑。对于初出茅庐的 Gopher 来说,首先要学习更重要、更简单的东西。那些过早学习反思的人混淆了他们对这些基础知识的理解。最好保持一臂之力,直到图片的其余部分清晰为止。
-抢
那说,
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]
- 3 回答
- 0 关注
- 188 浏览
添加回答
举报