Will copying value based interface make another copy of underlying value object?

389 views
Skip to first unread message

xingtao zhao

unread,
Jan 17, 2014, 2:19:50 PM1/17/14
to golan...@googlegroups.com
I am confused how copying of interface works. Here is an example:

type Interface interface {
DoSomething()
}

type S struct {
a []int
b float64
}

func NewS(length int, alpha float64) S {
return S{ make([]int, length), alpha }
}

func (s S) DoSomething() {
}

func main() {
s1 := NewS(10, 1.0)
s2 := s1  // Here we create a new copy of S
var i1 Interface
i1 = s1
i2 := i1
}
 

Here my question is:
  1. as S implement Interface (not *S), when we assign s1 to i1, are we making a new copy of S for i1 to point to, or i1 will point to s1?
  2. when we assign i1 to i2, will i1 and i2 point to the same S object, or different ones?

Brad Fitzpatrick

unread,
Jan 17, 2014, 2:25:43 PM1/17/14
to xingtao zhao, golang-nuts
"point to"?  Like you noted, S implements the interface, not *S, so there's logically an S _value_ in the interface value i1 and i2, not a *S.
 
It makes a copy, but a shallow copy... the float and slice header will be copied, but because the slice internally holds a pointer, mutations made to the "a []int" via i1 will be seen by i2.

But change it to "a [2]int" (an array) and you can verify that copies are being made.


xingtao zhao

unread,
Jan 17, 2014, 2:38:34 PM1/17/14
to golan...@googlegroups.com, xingtao zhao

Yeah, great! That meets my expectation!

Here is a verification of that in the playground: http://play.golang.org/p/dTZDZSH0MZ

Jeremy Matanky

unread,
Jan 17, 2014, 9:01:40 PM1/17/14
to golan...@googlegroups.com
If you print the address of each variable , you see they all have different addresses. http://play.golang.org/p/6RYcsvEHMy

xingtao zhao

unread,
Jan 18, 2014, 12:57:36 AM1/18/14
to golan...@googlegroups.com
In fact, an interface is something like:

type interface struct {
typ *type 
data uintptr 
}

So we should not test the address of i1 and i2. Instead we need to check if i1.data, i2.data, &s1, &s2 are the same or not. But I am not very sure how to get i1.data and i2.data. 

Jesse McNelis

unread,
Jan 18, 2014, 2:15:38 AM1/18/14
to xingtao zhao, golang-nuts
On Sat, Jan 18, 2014 at 4:57 PM, xingtao zhao <zhaox...@gmail.com> wrote:
In fact, an interface is something like:

type interface struct {
typ *type 
data uintptr 
}

So we should not test the address of i1 and i2. Instead we need to check if i1.data, i2.data, &s1, &s2 are the same or not. But I am not very sure how to get i1.data and i2.data. 

It's intentional that you can't address i1.data or i2.data.
Semantically a value in an interface functions like a value outside an interface and gets copied during assignment. But since the value isn't addressable while inside the interface most of the copying can be optimised away.

http://research.swtch.com/interfaces explains it really well.


Reply all
Reply to author
Forward
0 new messages