2016-04-10 2 views
2

В настоящее время я изучаю 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) 
} 

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

Выход:

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), кажется, что он непосредственно указывает на сам указатель, не касаясь фактического объекта.

Что мне не хватает?

ответ

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

1

Объясняя @ записку Uvelichitel на копии по значению,

o1 := <0x10434120> 
m := map[string]*obj{ 
    "foo": <0x10434120>, 
} 

o1.a = "WWW" // <0x10434120>.a = "WWW" changing both places 

o1 = nil 
m["foo"] // still is <0x10434120> 
Смежные вопросы