FAQ
I can write a package with a function like this:

     func Foo(r *os.File)

But if I want to be more general, want to use a io.Reader instead? This
won't work:

     func Foo(r *io.Reader)

It has to be this:

     func Foo(r io.Reader)

Why is this? Won't this copy the thing?

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Dmitry Vyukov at Jul 4, 2014 at 11:26 am

    On Fri, Jul 4, 2014 at 3:22 PM, Peter Kleiweg wrote:
    I can write a package with a function like this:

    func Foo(r *os.File)

    But if I want to be more general, want to use a io.Reader instead? This
    won't work:

    func Foo(r *io.Reader)
    This works.

    It has to be this:

    func Foo(r io.Reader)

    Why is this? Won't this copy the thing?
    interface{} is just 2 words, copying it is very cheap.
    interface copy does not copy the stored object, interface assignment can

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Kleiweg at Jul 4, 2014 at 11:38 am

    Op vrijdag 4 juli 2014 13:26:31 UTC+2 schreef Dmitry Vyukov:

    On Fri, Jul 4, 2014 at 3:22 PM, Peter Kleiweg <pkle...@xs4all.nl
    <javascript:>> wrote:
    I can write a package with a function like this:

    func Foo(r *os.File)

    But if I want to be more general, want to use a io.Reader instead? This
    won't work:

    func Foo(r *io.Reader)
    This works.
    No, it doesn't. See http://play.golang.org/p/FpInrZULnU

    It has to be this:

    func Foo(r io.Reader)

    Why is this? Won't this copy the thing?
    interface{} is just 2 words, copying it is very cheap.
    interface copy does not copy the stored object, interface assignment can
    I don't understand this.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dmitry Vyukov at Jul 4, 2014 at 11:46 am

    On Fri, Jul 4, 2014 at 3:38 PM, Peter Kleiweg wrote:
    Op vrijdag 4 juli 2014 13:26:31 UTC+2 schreef Dmitry Vyukov:
    On Fri, Jul 4, 2014 at 3:22 PM, Peter Kleiweg wrote:
    I can write a package with a function like this:

    func Foo(r *os.File)

    But if I want to be more general, want to use a io.Reader instead? This
    won't work:

    func Foo(r *io.Reader)
    This works.

    No, it doesn't. See http://play.golang.org/p/FpInrZULnU
    no, it does:
    http://play.golang.org/p/ohUkWqzAQo
    It has to be this:

    func Foo(r io.Reader)

    Why is this? Won't this copy the thing?
    interface{} is just 2 words, copying it is very cheap.
    interface copy does not copy the stored object, interface assignment can

    I don't understand this.
    interface copy is cheap

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Sugu Sougoumarane at Jul 5, 2014 at 3:20 am

    Why is this? Won't this copy the thing?
    interface{} is just 2 words, copying it is very cheap.
    interface copy does not copy the stored object, interface assignment
    can

    I don't understand this.
    interface copy is cheap
    Just to clarify here, interface copy is cheap only if the value it stores
    is <= one word, which includes pointers. If you store a large struct value
    in an interface (not pointer), it will cause the underlying value to get
    copied when you pass it around.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jesse McNelis at Jul 5, 2014 at 4:51 am

    On Sat, Jul 5, 2014 at 1:20 PM, Sugu Sougoumarane wrote:
    Why is this? Won't this copy the thing?
    interface{} is just 2 words, copying it is very cheap.
    interface copy does not copy the stored object, interface assignment
    can

    I don't understand this.
    interface copy is cheap

    Just to clarify here, interface copy is cheap only if the value it stores is
    <= one word, which includes pointers. If you store a large struct value in
    an interface (not pointer), it will cause the underlying value to get copied
    when you pass it around.
    That's not true.
    If the value is larger than a pointer then it will be allocated on the
    heap somewhere and a pointer stored in the interface value.
    Since you can't address that value from your code, it's safe for the
    compiler not to copy that value each time you copy the interface
    value.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dan Kortschak at Jul 5, 2014 at 7:18 am
    Just to make that concrete, here you can see that behaviour; the copy only happens when a concrete version is requested by an assertion.

    http://play.golang.org/p/oYohb0I91Y
    On 05/07/2014, at 2:21 PM, "Jesse McNelis" wrote:

    That's not true.
    If the value is larger than a pointer then it will be allocated on the
    heap somewhere and a pointer stored in the interface value.
    Since you can't address that value from your code, it's safe for the
    compiler not to copy that value each time you copy the interface
    value.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Sugu Sougoumarane at Jul 7, 2014 at 6:25 pm
    Thanks for the clarification. I'm glad to hear about this current behavior.
    I got confused by a conversation in a different mailing list that led me to
    believe that this was not the case.
    On Saturday, July 5, 2014 12:18:48 AM UTC-7, kortschak wrote:

    Just to make that concrete, here you can see that behaviour; the copy only
    happens when a concrete version is requested by an assertion.

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

    On 05/07/2014, at 2:21 PM, "Jesse McNelis" <jes...@jessta.id.au
    <javascript:>> wrote:
    That's not true.
    If the value is larger than a pointer then it will be allocated on the
    heap somewhere and a pointer stored in the interface value.
    Since you can't address that value from your code, it's safe for the
    compiler not to copy that value each time you copy the interface
    value.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dan Kortschak at Jul 8, 2014 at 4:13 am
    What I wrote is broadly correct, but sublty misinterprettable; any action that makes the interface concrete has the same effect, as can be seen here http://play.golang.org/p/XKI047WWzd

    On 08/07/2014, at 3:55 AM, "Sugu Sougoumarane" wrote:

    Thanks for the clarification. I'm glad to hear about this current behavior.
    I got confused by a conversation in a different mailing list that led me to believe that this was not the case.

    On Saturday, July 5, 2014 12:18:48 AM UTC-7, kortschak wrote:
    Just to make that concrete, here you can see that behaviour; the copy only happens when a concrete version is requested by an assertion.

    http://play.golang.org/p/oYohb0I91Y
    On 05/07/2014, at 2:21 PM, "Jesse McNelis" wrote:

    That's not true.
    If the value is larger than a pointer then it will be allocated on the
    heap somewhere and a pointer stored in the interface value.
    Since you can't address that value from your code, it's safe for the
    compiler not to copy that value each time you copy the interface
    value.
    --
    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+unsubscribe@googlegroups.com .
    For more options, visit https://groups.google.com/d/optout.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jesse McNelis at Jul 4, 2014 at 11:59 am

    On Fri, Jul 4, 2014 at 9:38 PM, Peter Kleiweg wrote:
    It has to be this:

    func Foo(r io.Reader)

    Why is this? Won't this copy the thing?
    interface{} is just 2 words, copying it is very cheap.
    interface copy does not copy the stored object, interface assignment can
    I don't understand this.
    Function calls in Go (like most other languages) is 'pass by value'.
    The values passed to the function are copied on to the stack for the
    function to access.
    In languages without complex values type (i.e. structs) these values
    are either primitive values (ints, floats etc) or they are
    references(pointers) to objects.

    Interface values in Go are the size of two pointers, one pointer to
    type information and the other is a pointer to the value currently
    stored in the interface value. eg. an io.Reader that you've assigned
    an *os.File to will contain that *os.File pointer and a pointer to the
    *os.File type information.

    Passing interface values to a function copies the interface value.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • David Symonds at Jul 4, 2014 at 2:04 pm
    Also, read http://research.swtch.com/interfaces.

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Kleiweg at Jul 4, 2014 at 6:45 pm

    Op vrijdag 4 juli 2014 16:04:22 UTC+2 schreef David Symonds:

    Also, read http://research.swtch.com/interfaces.
    If I read correctly, a value of type interface is a wrapper with a pointer
    to the real thing. So when I would use a pointer to the real thing as an
    argument to a function, I can get the same effect by passing the interface
    value itself, because it already is a pointer (conceptually).

    Is this correct?

    If so, is this part of the language design, or is it just how it happens to
    be implemented in the Go compiler. In other words, can I rely on an
    interface value always acting like a pointer to the real thing, or might it
    change in another implementation?

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris dollin at Jul 4, 2014 at 7:00 pm

    On 4 July 2014 19:45, Peter Kleiweg wrote:

    Op vrijdag 4 juli 2014 16:04:22 UTC+2 schreef David Symonds:
    If I read correctly, a value of type interface is a wrapper with a pointer
    to the real thing.
    Or with the real thing itself, if it will fit in a pointer-sized slot.

    So when I would use a pointer to the real thing as an argument to a
    function, I can get the same effect by passing the interface value itself,
    because it already is a pointer (conceptually).

    Is this correct?
    No. A pointer will let you update the variable it points to. The value
    in the interface is a copy of the thing it was assigned from, just like
    ordinary assignment/parameter-passing.

    Also, interfaces give you polymorphism, and pointers do not.

    If so, is this part of the language design, or is it just how it happens to
    be implemented in the Go compiler. In other words, can I rely on an
    interface value always acting like a pointer to the real thing, or might it
    change in another implementation?
    You can rely on the value stored in an interface being a copy, just like
    a variable of the appropriate type.

    And you can probably rely on the implementors not randomly discarding
    a nice space optimisation.

    Chris

    --
    Chris "allusive" Dollin

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Kleiweg at Jul 4, 2014 at 7:44 pm

    Op vrijdag 4 juli 2014 21:00:33 UTC+2 schreef chris dollin:

    On 4 July 2014 19:45, Peter Kleiweg <pkle...@xs4all.nl <javascript:>>
    wrote:
    Op vrijdag 4 juli 2014 16:04:22 UTC+2 schreef David Symonds:
    If I read correctly, a value of type interface is a wrapper with a
    pointer to the real thing.
    Or with the real thing itself, if it will fit in a pointer-sized slot.

    So when I would use a pointer to the real thing as an argument to a
    function, I can get the same effect by passing the interface value itself,
    because it already is a pointer (conceptually).

    Is this correct?
    No. A pointer will let you update the variable it points to. The value
    in the interface is a copy of the thing it was assigned from, just like
    ordinary assignment/parameter-passing.
    Then what is happening here? http://play.golang.org/p/8TkDe-0Gw-

    Why should there be a '*' in the definition of p1, and not in that of p2?

    p1 gets the pointer os.Stdout.
    What does p2 get? Something that embeds that pointer? Or something that
    embeds a copy of that pointer?

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • DV at Jul 4, 2014 at 10:40 pm

    On Friday, July 4, 2014 1:44:28 PM UTC-6, Peter Kleiweg wrote:
    Op vrijdag 4 juli 2014 21:00:33 UTC+2 schreef chris dollin:
    On 4 July 2014 19:45, Peter Kleiweg wrote:

    Op vrijdag 4 juli 2014 16:04:22 UTC+2 schreef David Symonds:
    If I read correctly, a value of type interface is a wrapper with a
    pointer to the real thing.
    Or with the real thing itself, if it will fit in a pointer-sized slot.

    So when I would use a pointer to the real thing as an argument to a
    function, I can get the same effect by passing the interface value itself,
    because it already is a pointer (conceptually).

    Is this correct?
    No. A pointer will let you update the variable it points to. The value
    in the interface is a copy of the thing it was assigned from, just like
    ordinary assignment/parameter-passing.
    Then what is happening here? http://play.golang.org/p/8TkDe-0Gw-

    Why should there be a '*' in the definition of p1, and not in that of p2?
    p1 needs a parameter that is a pointer to an os.File. os.Stdout is a
    pointer to an os.File.
    p2 needs *something* that implements the io,.Writer interface. That
    "something" might be a pointer, might not be. In your case, it is, since
    the Write method the File struct needs a pointer receiver, so you *have* to
    pass in a pointer to os.File to satisfy the io.Writer interface.

    It generally doesn't make sense to declare a function that takes a pointer
    to an interface, e.g. *io.Writer. It's not very useful - io.Writer itself
    might *contain* a pointer (as in your p2) example and all is fine.

    I think you may be confused about what interfaces in Go are and how they
    work. These might help:
    http://golang.org/doc/faq#pointer_to_interface
    http://golang.org/doc/faq#different_method_sets


    p1 gets the pointer os.Stdout.
    What does p2 get? Something that embeds that pointer? Or something that
    embeds a copy of that pointer?
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedJul 4, '14 at 11:22a
activeJul 8, '14 at 4:13a
posts15
users8
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase