英文:
Go: delete an object by its pointer
问题
我目前正在学习golang,并且有以下的代码。我的想法是创建一个带有指向它的指针的对象,并且我想使用其中一个指针来修改和删除对象。
package main
import "fmt"
type obj struct {
a int
b string
}
func main() {
o1 := &obj{1, "hello"}
o2 := &obj{2, "world"}
m := map[string]*obj{
"foo": o1,
"bar": o2,
}
fmt.Printf("1: %t %v\n", o1, o1)
fmt.Println("2:", m, m["foo"], o1)
o1.b = "WWWW"
fmt.Println("3:", m, m["foo"], o1)
o1 = nil
fmt.Println("4:", m, m["foo"], o1)
}
输出结果:
1: &{%!t(int=1) %!t(string=hello)} &{1 hello}
2: map[foo:0x10434120 bar:0x10434130] &{1 hello} &{1 hello}
3: map[foo:0x10434120 bar:0x10434130] &{1 WWWW} &{1 WWWW}
4: map[foo:0x10434120 bar:0x10434130] &{1 WWWW} <nil>
当我尝试更改对象的内部内容时,结果与我预期的一样(#3)。然而,当我尝试删除实际的对象时(#4),它似乎只是将指针本身设置为nil
,而不会触及实际的对象。
我漏掉了什么?
英文:
I'm currently learning golang, and have the following code.
The idea is to have an object with a number of pointers to it, and I'd like to modify and delete the object using one of the pointers.
package main
import "fmt"
type obj struct {
a int
b string
}
func main() {
o1 := &obj{1, "hello"}
o2 := &obj{2, "world"}
m := map[string]*obj{
"foo": o1,
"bar": o2,
}
fmt.Printf("1: %t %v\n", o1, o1)
fmt.Println("2:", m, m["foo"], o1)
o1.b = "WWWW"
fmt.Println("3:", m, m["foo"], o1)
o1 = nil
fmt.Println("4:", m, m["foo"], o1)
}
http://play.golang.org/p/lqQviVuTQN
Output:
1: &{%!t(int=1) %!t(string=hello)} &{1 hello}
2: map[foo:0x10434120 bar:0x10434130] &{1 hello} &{1 hello}
3: map[foo:0x10434120 bar:0x10434130] &{1 WWWW} &{1 WWWW}
4: map[foo:0x10434120 bar:0x10434130] &{1 WWWW} <nil>
Changing object's internals works as I expect (#3).
However when I try deleting the actual object (#4) it seems just nil
s the pointer itself without touching actual object.
What am I missing?
答案1
得分: 3
在Go语言中,所有的赋值操作都是按值传递的。
m := map[string]*obj{
"foo": o1,
"bar": o2,
}
这是一个赋值操作,所以foo
的值是o1
的一个副本。为了实现你的目标,你需要再增加一层间接引用。
o1 := &obj{1, "hello"}
o2 := &obj{2, "world"}
m := map[string]**obj{
"foo": &o1,
"bar": &o2,
}
你可以在这里查看示例代码:http://play.golang.org/p/XutneOziaM
英文:
All assignments in Go are copy by value.
m := map[string]*obj{
"foo": o1,
"bar": o2,
}
is an assignment, so value of foo is a copy of o1.
To achieve your goal you need one more level of indirection
o1 := &obj{1, "hello"}
o2 := &obj{2, "world"}
m := map[string]**obj{
"foo": &o1,
"bar": &o2,
}
答案2
得分: 1
解释一下@Uvelichitel关于按值复制的注释:
o1 := <0x10434120>
m := map[string]*obj{
"foo": <0x10434120>,
}
o1.a = "WWW" // <0x10434120>.a = "WWW" 同时改变两个位置
o1 = nil
m["foo"] // 仍然是 <0x10434120>
英文:
Explaining @Uvelichitel's note on copy by value,
o1 := <0x10434120>
m := map[string]*obj{
"foo": <0x10434120>,
}
o1.a = "WWW" // <0x10434120>.a = "WWW" changing both places
o1 = nil
m["foo"] // still is <0x10434120>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论