How to copy an interface variable to another in Go?

3,065 views
Skip to first unread message

hug...@gmail.com

unread,
Feb 4, 2015, 1:36:41 AM2/4/15
to golan...@googlegroups.com
Please take a look the codes below,  is it possible to copy variable a to x without knowing a is a pointer to Dog struct? It seems not possible even using "reflect"

package main

import (
"encoding/json"
"log"
)

type Named interface {
Nickname() string
}

type Dog struct {
Name string
Age  int
}

func (d *Dog) Nickname() string {
return d.Name
}

var mapping = map[string]Named{
"dog": &Dog{},
}

func main() {
a := mapping["dog"]
json.Unmarshal([]byte(`{"Name":"Alpha"}`), a)
var x Named

y := *a.(*Dog) //Can't just do y:=*a since a is  an interface
x = &y

b := mapping["dog"]
json.Unmarshal([]byte(`{"Name":"Beta"}`), b)

log.Println(a, b, x)
}

chris dollin

unread,
Feb 4, 2015, 9:16:20 AM2/4/15
to hug...@gmail.com, golang-nuts
It seems to me that the use of JSON unmarshalling isn't
anything to do with your problem (copying interface variables), yes?

You can copy an interface variable with a simple assignment.
You get two variables that hold the same value.

But like any Go assignment, it copies pointers /as pointers/,
not making copies of the pointed-to thing. Similarly for
slices and maps and channels.

So if you copy a &Dog, you get another pointer to the same
Dog, and if you poke that Dog through one pointer, eg changing
their Name to Scamper, then you will see that new name when
you look through the other pointer.

Which is (part of) what's happening in your example, where in
a complicated way you change the single Dog's name to Beta.
There's only one Dog, the one you put into the map.

Does that help?

Chris
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.



--
Chris "allusive" Dollin

Klaus Post

unread,
Feb 4, 2015, 9:43:11 AM2/4/15
to golan...@googlegroups.com
Hi!

It seems like you are doing something too complicated if you have to do this.

However, if you *want* to copy the value of an interface you can do it with reflection:


I tried to write what happens each step. However, as you might be able to tell from the complex code, "if you have to use reflection you are probably doing something wrong". However, since you didn't describe *why* you need to copy it, I cannot help you.

Hope it helps you anyway.

/Klaus

Egon

unread,
Feb 4, 2015, 10:06:55 AM2/4/15
to golan...@googlegroups.com
I would say implement a

type Cloneable interface { Clone() Clonable }

or any more specific version, if you need to do copies.

+ Egon

Hugo Zhu

unread,
Feb 4, 2015, 11:27:37 AM2/4/15
to chris dollin, golang-nuts
thanks, I have figured it out.

--
Hugo Zhu

Sent from my iPhone
Reply all
Reply to author
Forward
0 new messages