Go:通过指针删除一个对象

huangapple go评论117阅读模式
英文:

Go: delete an object by its pointer

问题

我目前正在学习golang,并且有以下的代码。我的想法是创建一个带有指向它的指针的对象,并且我想使用其中一个指针来修改和删除对象。

  1. package main
  2. import "fmt"
  3. type obj struct {
  4. a int
  5. b string
  6. }
  7. func main() {
  8. o1 := &obj{1, "hello"}
  9. o2 := &obj{2, "world"}
  10. m := map[string]*obj{
  11. "foo": o1,
  12. "bar": o2,
  13. }
  14. fmt.Printf("1: %t %v\n", o1, o1)
  15. fmt.Println("2:", m, m["foo"], o1)
  16. o1.b = "WWWW"
  17. fmt.Println("3:", m, m["foo"], o1)
  18. o1 = nil
  19. fmt.Println("4:", m, m["foo"], o1)
  20. }

输出结果:

  1. 1: &{%!t(int=1) %!t(string=hello)} &{1 hello}
  2. 2: map[foo:0x10434120 bar:0x10434130] &{1 hello} &{1 hello}
  3. 3: map[foo:0x10434120 bar:0x10434130] &{1 WWWW} &{1 WWWW}
  4. 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.

  1. package main
  2. import &quot;fmt&quot;
  3. type obj struct {
  4. a int
  5. b string
  6. }
  7. func main() {
  8. o1 := &amp;obj{1, &quot;hello&quot;}
  9. o2 := &amp;obj{2, &quot;world&quot;}
  10. m := map[string]*obj{
  11. &quot;foo&quot;: o1,
  12. &quot;bar&quot;: o2,
  13. }
  14. fmt.Printf(&quot;1: %t %v\n&quot;, o1, o1)
  15. fmt.Println(&quot;2:&quot;, m, m[&quot;foo&quot;], o1)
  16. o1.b = &quot;WWWW&quot;
  17. fmt.Println(&quot;3:&quot;, m, m[&quot;foo&quot;], o1)
  18. o1 = nil
  19. fmt.Println(&quot;4:&quot;, m, m[&quot;foo&quot;], o1)
  20. }

http://play.golang.org/p/lqQviVuTQN

Output:

  1. 1: &amp;{%!t(int=1) %!t(string=hello)} &amp;{1 hello}
  2. 2: map[foo:0x10434120 bar:0x10434130] &amp;{1 hello} &amp;{1 hello}
  3. 3: map[foo:0x10434120 bar:0x10434130] &amp;{1 WWWW} &amp;{1 WWWW}
  4. 4: map[foo:0x10434120 bar:0x10434130] &amp;{1 WWWW} &lt;nil&gt;

Changing object's internals works as I expect (#3).
However when I try deleting the actual object (#4) it seems just nils the pointer itself without touching actual object.

What am I missing?

答案1

得分: 3

在Go语言中,所有的赋值操作都是按值传递的。

  1. m := map[string]*obj{
  2. "foo": o1,
  3. "bar": o2,
  4. }

这是一个赋值操作,所以foo的值是o1的一个副本。为了实现你的目标,你需要再增加一层间接引用。

  1. o1 := &obj{1, "hello"}
  2. o2 := &obj{2, "world"}
  3. m := map[string]**obj{
  4. "foo": &o1,
  5. "bar": &o2,
  6. }

你可以在这里查看示例代码:http://play.golang.org/p/XutneOziaM

英文:

All assignments in Go are copy by value.

  1. m := map[string]*obj{
  2. &quot;foo&quot;: o1,
  3. &quot;bar&quot;: o2,
  4. }

is an assignment, so value of foo is a copy of o1.
To achieve your goal you need one more level of indirection

  1. o1 := &amp;obj{1, &quot;hello&quot;}
  2. o2 := &amp;obj{2, &quot;world&quot;}
  3. m := map[string]**obj{
  4. &quot;foo&quot;: &amp;o1,
  5. &quot;bar&quot;: &amp;o2,
  6. }

http://play.golang.org/p/XutneOziaM

答案2

得分: 1

解释一下@Uvelichitel关于按值复制的注释:

  1. o1 := <0x10434120>
  2. m := map[string]*obj{
  3. "foo": <0x10434120>,
  4. }
  5. o1.a = "WWW" // <0x10434120>.a = "WWW" 同时改变两个位置
  6. o1 = nil
  7. m["foo"] // 仍然是 <0x10434120>
英文:

Explaining @Uvelichitel's note on copy by value,

  1. o1 := &lt;0x10434120&gt;
  2. m := map[string]*obj{
  3. &quot;foo&quot;: &lt;0x10434120&gt;,
  4. }
  5. o1.a = &quot;WWW&quot; // &lt;0x10434120&gt;.a = &quot;WWW&quot; changing both places
  6. o1 = nil
  7. m[&quot;foo&quot;] // still is &lt;0x10434120&gt;

huangapple
  • 本文由 发表于 2016年4月10日 23:52:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/36531948.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定