Assignment: shallow or deep copy?

7,977 views
Skip to first unread message

Kejia

unread,
Jan 9, 2011, 7:40:34 PM1/9/11
to golang-nuts
Hello people,

I don't have a go environment and just have a simple question: Is
assignment to a variable a shallow copy or deep copy? For example:
``
type Pet structure {...}

var huski Pet = new(Pet)
dog := huski
''
Are both `dog' and `huski' pointing from the same address?

Andrew Gerrand

unread,
Jan 9, 2011, 8:01:43 PM1/9/11
to Kejia, golang-nuts
A go assignment is a copy of the value itself.

If you assign a pointer value, a copy of that pointer value is made.
The thing the pointer points at is not copied.

> type Pet structure {...}
>
> var huski Pet = new(Pet)
> dog := huski

This code won't compile. new(Pet) returns a value of type *Pet, while
the variable huski is of type Pet.

In this example, huski and dog are both pointers to the same Pet:

var huski *Pet = new(Pet)
dog := huski

In this example, dog is a copy of huski, which is a Pet value:

var huski Pet = Pet{}
dog := huski

You can then modify the huski value without affecting dog.

Andrew

Ostsol

unread,
Jan 9, 2011, 8:08:38 PM1/9/11
to golang-nuts
In Go, almost everything is passed by value. Maps, slices, and
channels are reference types, so when passing one the receiver points
to the original object. In order to pass a reference to a struct, you
must pass a pointer. A correction to the code you posted would be:

type Pet struct { ... }

var huski *Pet = new(Pet)
dog := huski

'dog' now points the same Pet as 'huski'. 'dog's type is '*Pet', like
'huski'. (Also note that 'new' always returns a pointer.) Consider
the following code, though:

dog := *huski

The asterisk dereferences 'huski', so 'dog' is a copy of 'huski', and
'dog's type is 'Pet'.

-Daniel

Ostsol

unread,
Jan 9, 2011, 8:15:11 PM1/9/11
to golang-nuts
Addendum: even pointers are simply values, and as such are passed by
value. A map, slice, or channel is a pointer to underlying data, but
it is a pointer that cannot be dereferenced, like other pointers. It
is best to program in Go not thinking in terms of Java or Python, but
C.

-Daniel

Corey Thomasson

unread,
Jan 9, 2011, 8:51:28 PM1/9/11
to Ostsol, golang-nuts

This is really an implementation detail More than a spec detail. Slices and friends are for specification purposes a reference type. I believe That currently they're actually an underlying structure passed by value and the structure contains a pointer to the referenced data. Iirc

On 9 Jan 2011 20:15, "Ostsol" <ost...@gmail.com> wrote:

Addendum: even pointers are simply values, and as such are passed by
value.  A map, slice, or channel is a pointer to underlying data, but
it is a pointer that cannot be dereferenced, like other pointers.  It
is best to program in Go not thinking in terms of Java or Python, but
C.

-Daniel


On Jan 9, 6:08 pm, Ostsol <ost...@gmail.com> wrote:

> In Go, almost everything is passed by value. ...

Kejia

unread,
Jan 9, 2011, 9:23:24 PM1/9/11
to golang-nuts
Thank you for the answers.

Tibi

unread,
Jan 10, 2011, 3:45:41 AM1/10/11
to golang-nuts
In terms of optimization, do we need to think whether a variable
should be passed by value or by pointer value?
I mean if we would like to pass a big struct I guess it is better to
pass it by pointer value although we might not want to might not want
to modify the underlying data.

Tibor

xophos

unread,
Jan 10, 2011, 7:06:46 AM1/10/11
to golang-nuts
I would very much hope, that the go compiler (or a future Version of
it) can detect cases where a Struct is not written to and use a
pointer internally or even always using a copy on write mechanism.
In this case the Performance should be similar.

Johann Höchtl

unread,
Jan 10, 2011, 9:17:11 AM1/10/11
to golang-nuts


On Jan 10, 1:06 pm, xophos <xop...@gmail.com> wrote:
> I would very much hope, that the go compiler (or a future Version of
> it) can detect cases where a Struct is not written to and use a
> pointer internally or even always using a copy on write mechanism.
> In this case the Performance should be similar.
>
Such an optimisation would yield different behaviour dependent on
optimisation. Just think about interacting with an FFI. The receiver
has to know if it can expect a literal or a pointer. Only whole
program optimisation would make such optimisations possible.

Johann

Kejia

unread,
Jan 10, 2011, 6:01:51 PM1/10/11
to golang-nuts
It's tragedy to raise another big fat as Java :-)
Reply all
Reply to author
Forward
0 new messages