FAQ
With the following code I get "./interface.go:23: b.Attributes.X undefined
(type MessageAttributes has no field or method X)". This is where I'm
trying to set X = 2. This is simple example but what I'm basically trying
to do is use an interface type as a struct field so that that field can be
any one of the possible types. I want to always use a Message object but I
want the attributes to be of a specific type (Email, Push, SMS, ect.) but I
can't set any of the attributes because of this error.


package main

import "fmt"

type MessageAttributes interface {
     Foo() int
}

type Email struct {
     X int
}

func (e Email) Foo() int {
     return e.X * 2
}

type Message struct {
     Attributes MessageAttributes
}

func main() {
     b := Message{}
     b.Attributes.X = 2
     fmt.Println(b.Foo())
}

--
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 Feb 26, 2014 at 11:35 pm
    Define a setter, SetFoo(int) on Email and in the Message interface or do
    a type switch.
    On Wed, 2014-02-26 at 11:38 -0800, tbeauvais@gmail.com wrote:
    With the following code I get "./interface.go:23: b.Attributes.X undefined
    (type MessageAttributes has no field or method X)". This is where I'm
    trying to set X = 2. This is simple example but what I'm basically trying
    to do is use an interface type as a struct field so that that field can be
    any one of the possible types. I want to always use a Message object but I
    want the attributes to be of a specific type (Email, Push, SMS, ect.) but I
    can't set any of the attributes because of this error.


    package main

    import "fmt"

    type MessageAttributes interface {
    Foo() int
    }

    type Email struct {
    X int
    }

    func (e Email) Foo() int {
    return e.X * 2
    }

    type Message struct {
    Attributes MessageAttributes
    }

    func main() {
    b := Message{}
    b.Attributes.X = 2
    fmt.Println(b.Foo())
    }
    --
    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.
  • Travis Beauvais at Feb 26, 2014 at 11:45 pm
    I considered that but that would mean I have to do a setter for every
    possible attribute of Email, SMS, Voice, Push, etc. and I really didn't
    want to do that.

    I decided to take a different approach and bypassed this problem all
    together. Thanks though.
    On Wednesday, February 26, 2014 3:35:07 PM UTC-8, kortschak wrote:

    Define a setter, SetFoo(int) on Email and in the Message interface or do
    a type switch.
    On Wed, 2014-02-26 at 11:38 -0800, tbea...@gmail.com <javascript:> wrote:
    With the following code I get "./interface.go:23: b.Attributes.X undefined
    (type MessageAttributes has no field or method X)". This is where I'm
    trying to set X = 2. This is simple example but what I'm basically trying
    to do is use an interface type as a struct field so that that field can be
    any one of the possible types. I want to always use a Message object but I
    want the attributes to be of a specific type (Email, Push, SMS, ect.) but I
    can't set any of the attributes because of this error.


    package main

    import "fmt"

    type MessageAttributes interface {
    Foo() int
    }

    type Email struct {
    X int
    }

    func (e Email) Foo() int {
    return e.X * 2
    }

    type Message struct {
    Attributes MessageAttributes
    }

    func main() {
    b := Message{}
    b.Attributes.X = 2
    fmt.Println(b.Foo())
    }
    --
    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.
  • Joe Shaw at Feb 26, 2014 at 11:48 pm
    Hi,
    On Wednesday, February 26, 2014 2:38:59 PM UTC-5, Travis Beauvais wrote:

    With the following code I get "./interface.go:23: b.Attributes.X undefined
    (type MessageAttributes has no field or method X)". This is where I'm
    trying to set X = 2. This is simple example but what I'm basically trying
    to do is use an interface type as a struct field so that that field can be
    any one of the possible types. I want to always use a Message object but I
    want the attributes to be of a specific type (Email, Push, SMS, ect.) but I
    can't set any of the attributes because of this error.
    You can't set X because it is defined on type Email, but Message.Attributes
    is of type MessageAttributes. Imagine you have another type, SMS:

    type SMS struct {
         Y string
    }

    func (s SMS) Foo() int {
         return len(s.Y)
    }

    This type satisfies the interface as you've defined it, but it doesn't have
    an X field on it. What should happen if you tried to assign b.Attributes.X
    = 2 in your example?

    You have two options here. The first, and better, choice is to have
    setting of the field be part of the interface:

    type MessageAttributes interface {
         Foo() int
         SetFoo(int)
    }

    Then instead of assigning b.Attributes.X = 2, you'd call b.SetFoo(2).

    The other option is to use a type switch to cast your MessageAttributes
    instance to a particular implementing type:

    b := Message{}
    b.Attributes = Email{}
    switch x := b.(type) {
    case Email:
         x.X = 2
    case SMS:
         x.Y = 100
    }

    Joe



    package main

    import "fmt"

    type MessageAttributes interface {
    Foo() int
    }

    type Email struct {
    X int
    }

    func (e Email) Foo() int {
    return e.X * 2
    }

    type Message struct {
    Attributes MessageAttributes
    }

    func main() {
    b := Message{}
    b.Attributes.X = 2
    fmt.Println(b.Foo())
    }
    --
    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.
  • Andrey mirtchovski at Feb 27, 2014 at 12:05 am

    b := Message{}
    b.Attributes = Email{}
    switch x := b.(type) {
    case Email:
    x.X = 2
    case SMS:
    x.Y = 100
    }
    the only caveat here is that x will be a copy. to have this work the
    methods satisfying the interface will have to be defined on *Email and
    *SMS respectively

    --
    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
postedFeb 26, '14 at 11:26p
activeFeb 27, '14 at 12:05a
posts5
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase