FAQ
A serious misunderstanding was recently found. What it means to embed an
interface in a struct is not understood correctly. The original
understanding of this (or at a least side-effect of it) was that embedding
an interface in a struct would ensure that the struct implements the
interface. If the struct did not implement the interface, a compilation
error would occur to notify me that the struct does not implement the
interface any longer.

This behavior might have changed from pre-go1 to go1 because I could have
sworn that this was the case at some point in time. The scenario that
occurred was: an interface that I have been using for some time now needed
a method added to it. Once the method was added, I expected to see several
compilation errors notifying me which structs embed the interface and do
not implement any longer. The program executed without any problem until
the new method was called on a passed type-assertion with a struct that did
not implement the method.

What is the point of embedding an interface inside a struct? Is there any?

--
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/groups/opt_out.

Search Discussions

  • Dan Kortschak at Mar 24, 2013 at 7:53 pm
    When the interface field holds a type that implements the interface then the struct type implements the interface.

    Remember that an interface type doesn't implement anything it just hold things that do.

    --
    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/groups/opt_out.
  • Jan Mercl at Mar 24, 2013 at 8:03 pm
    On Sun, Mar 24, 2013 at 8:49 PM, wrote:

    I'm not sure what/where the problem is. Please post an example of what
    you're doing, and what doesn't work as expected.

    -j

    PS: Some people understand code better than prose about code.

    --
    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/groups/opt_out.
  • Chrismiddle10 at Mar 24, 2013 at 8:14 pm
    A quick example:

    type MyInterface interface {
    Foo() string
    }

    type MyStruct struct {
    MyInterface
    }

    func (o *MyStruct) Foo() string {
    return "foo"
    }

    ...

    Then a some code that does something along the lines of the following will
    work without an issue.

    o := new( MyStruct )

    var i interface{}
    i = o

    if x, ok := i.(MyInterface); ok {
    x.Foo()
    }

    ...

    But the scenario that has presented itself to me is: I want to now modify
    interface by adding a method. For example:

    type MyInterface interface {
    Foo() string
    Bar() string
    }

    What I expected was a compilation error informing me that "MyStruct" does
    not implement the "MyInterface" interface any longer. Instead the following
    code compiles and panics. The panic is not a surprise. The fact that the
    type-assertion passed and the program compiled is.

    o := new( MyStruct )

    var i interface{}
    i = o

    if x, ok := i.(MyInterface); ok {
    x.Foo()
    x.Bar() // Once execution reaches this point a panic will occur.
    }





    --
    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/groups/opt_out.
  • Patrick Mylund Nielsen at Mar 24, 2013 at 8:32 pm
    Why not just leave out the embedding, and use the values as MyInterface
    instead of interface{}--then you don't have to type-assert constantly, and
    you get compile-time sanity checks. Go doesn't have "implements"--anything
    that has the right method set implements one or more interfaces. If, at
    compile-time, a value that does not implement an interface is passed to a
    function that expects one, the compiler will complain. This is not the case
    for interface{} since all values implement the empty interface (none or
    more methods.)

    On Sun, Mar 24, 2013 at 9:14 PM, wrote:

    A quick example:

    type MyInterface interface {
    Foo() string
    }

    type MyStruct struct {
    MyInterface
    }

    func (o *MyStruct) Foo() string {
    return "foo"
    }

    ...

    Then a some code that does something along the lines of the following will
    work without an issue.

    o := new( MyStruct )

    var i interface{}
    i = o

    if x, ok := i.(MyInterface); ok {
    x.Foo()
    }

    ...

    But the scenario that has presented itself to me is: I want to now modify
    interface by adding a method. For example:

    type MyInterface interface {
    Foo() string
    Bar() string
    }

    What I expected was a compilation error informing me that "MyStruct" does
    not implement the "MyInterface" interface any longer. Instead the following
    code compiles and panics. The panic is not a surprise. The fact that the
    type-assertion passed and the program compiled is.

    o := new( MyStruct )

    var i interface{}
    i = o

    if x, ok := i.(MyInterface); ok {
    x.Foo()
    x.Bar() // Once execution reaches this point a panic will occur.

    }





    --
    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/groups/opt_out.

    --
    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/groups/opt_out.
  • Jan Mercl at Mar 24, 2013 at 8:32 pm
    On Sun, Mar 24, 2013 at 9:14 PM, wrote:

    Everything works correctly.

    We're talking about anonymous fields of a struct
    (http://golang.org/ref/spec#Struct_types). A struct with an anonymous
    field satisfies every interface which is a superset of the methods of
    the anonymous field. That's why it compiles.

    However, in your example, the anonymous field is left at its zero
    value (nil). When invoking x.Foo(), 'func (o *MyStruct) Foo()' is
    called, the anonymous field is not involved (MyStruct effectively
    overides the Foo method). But when x.Bar() is invoked, it's not the
    same. MyStruct doesn't override/implement it. So the value in the
    embedded field (which is statically guaranteed to implement
    MyInterface) is consulted to figure out which concrete, non interface
    type method .Bar should be invoked, but the embedded field is nil.
    Kaboom. FYI: It's an equivalent of:
    http://play.golang.org/p/77RMvnuDke

    Conclusion: The code will work as expected once the embedded field
    will not be left uninitialized.

    -j

    --
    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/groups/opt_out.
  • Chrismiddle10 at Mar 24, 2013 at 9:26 pm
    Who knows what series of circumstances led me to believe that an embedded
    interface had the meaning that I thought it did. It is a little
    disappointing. Thanks for your input, everyone.

    --
    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/groups/opt_out.
  • Jimmy frasche at Mar 24, 2013 at 9:34 pm
    I believe what you want is

    var _ MyInterface = MyStruct{} //Or &MyStruct{}, if necessary

    this will fail at compile time if MyStruct does not have the method
    set required by MyInterface

    --
    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/groups/opt_out.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedMar 24, '13 at 7:50p
activeMar 24, '13 at 9:34p
posts8
users5
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase