type T struct {
Id int
Name string
}
func Copy(a *T, b *T) error {
b.Id=5
b.Name="gert"
a = b
return nil
}
Run Code Online (Sandbox Code Playgroud)
a 仍然是空的,我必须这样做
func Copy(a *T, b *T) error {
b.Id = 5
b.Name = "gert"
a.Id = b.Id
a.Name = b.Name
return nil
}
Run Code Online (Sandbox Code Playgroud)
现在a是一样的b
为什么我怎么能复制*b到*a直接?
Bra*_*ncy 71
你的第一个例子几乎是对的.您将指针传递给两个对象.你把这些指针放在变量A和B中.但A和B是局部变量,所以当你说a=b你只是说"忘记A(本地)中的内容"时.程序的其余部分仍然指向这两个原始对象.
如果要将B处的数据结构复制到A 处的数据结构中,请执行以下操作:
*a = *b;
Run Code Online (Sandbox Code Playgroud)
正如dmikalova在下面的评论中所指出的,这只是复制结构 - 但不是结构所指向的任何数据.如果你的struct有一个指针,它指向的数据现在由两个副本共享(因为它只复制了指针).
从技术上讲,字符串总是指针,所以它们永远不会被复制为结构的一部分.但是因为字符串是不可变的(并且Go具有垃圾收集),字符串"感觉"就像它们是你的结构的一部分,并且你不必担心低级别的字符串共享,它可以神奇地节省你的记忆,而你不必考虑关于它.
Dav*_*rth 14
在go中,参数按值传递.
并且*T是指向T的指针.将它想象成一个int,告诉你T在哪里.因此,"a"指向T的一个实例,b指向另一个实例.
在你的复制功能中,你说的是指向b的"T"(如果这是有道理的).你想要的是说a的T应该与b的T相同
你通过解除引用指针来做到这一点.
所以,而不是a = b(改变我的局部变量"a"指向任何"b"点)你使用*a =*b(将a的T改为等于b的T)
希望这是有道理的,这是一个你的应用程序修改为"做正确的事情"的例子.请注意,此处不需要您的复制功能,它可以用于说明. 播放示例
import "fmt"
type T struct {
Id int
Name string
}
func Copy(a *T, b *T) error {
b.Id = 5
b.Name = "gert"
a = b
return nil
}
func CopyThatActuallyCopies(a *T, b *T) error {
b.Id = 5
b.Name = "gert"
*a = *b
return nil
}
func main() {
var a = &T{1, "one"}
var b = &T{2, "two"}
fmt.Println(a, b)
Copy(a, b)
fmt.Println(a, b)
CopyThatActuallyCopies(a, b)
fmt.Println(a, b)
}
Run Code Online (Sandbox Code Playgroud)
Moh*_*sen 14
框架开发人员的一般解决方
func CloneValue(source interface{}, destin interface{}) {
x := reflect.ValueOf(source)
if x.Kind() == reflect.Ptr {
starX := x.Elem()
y := reflect.New(starX.Type())
starY := y.Elem()
starY.Set(starX)
reflect.ValueOf(destin).Elem().Set(y.Elem())
} else {
destin = x.Interface()
}
}
Run Code Online (Sandbox Code Playgroud)
所以:
CloneValue(old, new)
Run Code Online (Sandbox Code Playgroud)
请参阅play.golang.org中的此代码
所以你可以在运行时传递任何类型,只要你确定source和destin都是相同的类型,(并且destin是指向该类型的指针).