FAQ
Disclaimer: It's most likely that I'm missing something or I'm wrong as a
Noob (& OOly corrupted mind), but I've failed to rationalize this.

Line of Thought:

Mixins can be implemented in Go (1.4.1) using embedding and since `struct{}`
occupies no memory (as I understand) it fits for the situations that we
want to add some functionality or just add a method to a type that may
actually has nothing to do with it's state, but we like to avoid
`CleanThing` or `ParseThing` and instead write `thing.Parse()`.

So having:

type X struct{}


func (x X) F() {

     fmt.Println("functionality in X.F()")

}


type Y struct{ X }

type Z struct{ Y }


Then if we do:

var z Z

z.F()


Will give us:

functionality in X.F()


So far so good.

Now let's add another type `OX` with method `F()` and embed it in `Z`:

type Z struct {

     Y

     OX

}


type OX struct{} // overriding X


func (x OX) F() {

     fmt.Println("functionality in OX.F()")

}


Interesting! Now we get `functionality in OX.F()` which shows us that Go
compiler searches for the method, starting from type it self and then the
last embedded type. We can check that by adding `F()` to `Z`:

func (x Z) F() {

     fmt.Println("functionality in Z.F()")

}


The output is `functionality in Z.F()`. Now if we remove the `Z.F()` method
and add `F()` to `Y`:

//func (x Z) F() {

// fmt.Println("functionality in Z.F()")

//}


func (x Y) F() {

     fmt.Println("functionality in Y.F()")

}


Then we see this error `ambiguous selector z.F`; redirecting via pointers
makes no difference.

Question 1: Why that's so?

The extra level of indirection `Y` meant for something else, but brought me
to this. And as I've guessed `func (t T) String() string{}` is an
exception. This code:

type X struct{}


func (x X) String() string {

     return "in X.String()"

}


type Y struct{ X }

type Z struct {

     Y

     OX

}


type OX struct{} // overriding X


func (x OX) String() string {

     return "in OX.String()"

}


func (x Y) String() string {

     return "in Y.String()"

}


And then this:

var z Z

fmt.Println(z)


Gives us:

{in Y.String() in OX.String()}

Which is logical. But if we use pointer receivers:

import (

     "fmt"

     "testing"

)


func TestIt(t *testing.T) {

     var z Z

     fmt.Println(z)

}


type X struct{}


func (x *X) String() string {

     return "in X.String()"

}


type Y struct{ X }

type Z struct {

     Y

     OX

}


type OX struct{} // overriding X


func (x *OX) String() string {

     return "in OX.String()"

}


func (x *Y) String() string {

     return "in Y.String()"

}


Will print out:

{{{}} {}}

Question 2: Why is that's so?

--
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

  • Justin Israel at Feb 2, 2015 at 8:33 am
    Side note - I can't really read your code examples very easily with the
    crazy syntax highlighting.
    On Mon Feb 02 2015 at 9:24:15 PM dc0d wrote:

    Disclaimer: It's most likely that I'm missing something or I'm wrong as a
    Noob (& OOly corrupted mind), but I've failed to rationalize this.

    Line of Thought:

    Mixins can be implemented in Go (1.4.1) using embedding and since `struct
    {}` occupies no memory (as I understand) it fits for the situations that
    we want to add some functionality or just add a method to a type that may
    actually has nothing to do with it's state, but we like to avoid
    `CleanThing` or `ParseThing` and instead write `thing.Parse()`.

    So having:

    type X struct{}


    func (x X) F() {

    fmt.Println("functionality in X.F()")

    }


    type Y struct{ X }

    type Z struct{ Y }


    Then if we do:

    var z Z

    z.F()


    Will give us:

    functionality in X.F()


    So far so good.

    Now let's add another type `OX` with method `F()` and embed it in `Z`:

    type Z struct {

    Y

    OX

    }


    type OX struct{} // overriding X


    func (x OX) F() {

    fmt.Println("functionality in OX.F()")

    }


    Interesting! Now we get `functionality in OX.F()` which shows us that Go
    compiler searches for the method, starting from type it self and then the
    last embedded type. We can check that by adding `F()` to `Z`:

    func (x Z) F() {

    fmt.Println("functionality in Z.F()")

    }


    The output is `functionality in Z.F()`. Now if we remove the `Z.F()`
    method and add `F()` to `Y`:

    //func (x Z) F() {

    // fmt.Println("functionality in Z.F()")

    //}


    func (x Y) F() {

    fmt.Println("functionality in Y.F()")

    }


    Then we see this error `ambiguous selector z.F`; redirecting via pointers
    makes no difference.

    Question 1: Why that's so?

    The extra level of indirection `Y` meant for something else, but brought
    me to this. And as I've guessed `func (t T) String() string{}` is an
    exception. This code:

    type X struct{}


    func (x X) String() string {

    return "in X.String()"

    }


    type Y struct{ X }

    type Z struct {

    Y

    OX

    }


    type OX struct{} // overriding X


    func (x OX) String() string {

    return "in OX.String()"

    }


    func (x Y) String() string {

    return "in Y.String()"

    }


    And then this:

    var z Z

    fmt.Println(z)


    Gives us:

    {in Y.String() in OX.String()}

    Which is logical. But if we use pointer receivers:

    import (

    "fmt"

    "testing"

    )


    func TestIt(t *testing.T) {

    var z Z

    fmt.Println(z)

    }


    type X struct{}


    func (x *X) String() string {

    return "in X.String()"

    }


    type Y struct{ X }

    type Z struct {

    Y

    OX

    }


    type OX struct{} // overriding X


    func (x *OX) String() string {

    return "in OX.String()"

    }


    func (x *Y) String() string {

    return "in Y.String()"

    }


    Will print out:

    {{{}} {}}

    Question 2: Why is that's so?

    --
    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.
  • Dc0d at Feb 2, 2015 at 8:41 am
    Thanks;

    I'm sorry, I wasn't paying attention. Since posts can not be edited, should
    I re-post it?
    On Monday, February 2, 2015 at 12:03:08 PM UTC+3:30, Justin Israel wrote:

    Side note - I can't really read your code examples very easily with the
    crazy syntax highlighting.

    On Mon Feb 02 2015 at 9:24:15 PM dc0d <kaveh.sh...@gmail.com <javascript:>>
    wrote:
    Disclaimer: It's most likely that I'm missing something or I'm wrong as a
    Noob (& OOly corrupted mind), but I've failed to rationalize this.

    Line of Thought:

    Mixins can be implemented in Go (1.4.1) using embedding and since `struct
    {}` occupies no memory (as I understand) it fits for the situations that
    we want to add some functionality or just add a method to a type that may
    actually has nothing to do with it's state, but we like to avoid
    `CleanThing` or `ParseThing` and instead write `thing.Parse()`.

    So having:

    type X struct{}


    func (x X) F() {

    fmt.Println("functionality in X.F()")

    }


    type Y struct{ X }

    type Z struct{ Y }


    Then if we do:

    var z Z

    z.F()


    Will give us:

    functionality in X.F()


    So far so good.

    Now let's add another type `OX` with method `F()` and embed it in `Z`:

    type Z struct {

    Y

    OX

    }


    type OX struct{} // overriding X


    func (x OX) F() {

    fmt.Println("functionality in OX.F()")

    }


    Interesting! Now we get `functionality in OX.F()` which shows us that Go
    compiler searches for the method, starting from type it self and then the
    last embedded type. We can check that by adding `F()` to `Z`:

    func (x Z) F() {

    fmt.Println("functionality in Z.F()")

    }


    The output is `functionality in Z.F()`. Now if we remove the `Z.F()`
    method and add `F()` to `Y`:

    //func (x Z) F() {

    // fmt.Println("functionality in Z.F()")

    //}


    func (x Y) F() {

    fmt.Println("functionality in Y.F()")

    }


    Then we see this error `ambiguous selector z.F`; redirecting via
    pointers makes no difference.

    Question 1: Why that's so?

    The extra level of indirection `Y` meant for something else, but brought
    me to this. And as I've guessed `func (t T) String() string{}` is an
    exception. This code:

    type X struct{}


    func (x X) String() string {

    return "in X.String()"

    }


    type Y struct{ X }

    type Z struct {

    Y

    OX

    }


    type OX struct{} // overriding X


    func (x OX) String() string {

    return "in OX.String()"

    }


    func (x Y) String() string {

    return "in Y.String()"

    }


    And then this:

    var z Z

    fmt.Println(z)


    Gives us:

    {in Y.String() in OX.String()}

    Which is logical. But if we use pointer receivers:

    import (

    "fmt"

    "testing"

    )


    func TestIt(t *testing.T) {

    var z Z

    fmt.Println(z)

    }


    type X struct{}


    func (x *X) String() string {

    return "in X.String()"

    }


    type Y struct{ X }

    type Z struct {

    Y

    OX

    }


    type OX struct{} // overriding X


    func (x *OX) String() string {

    return "in OX.String()"

    }


    func (x *Y) String() string {

    return "in Y.String()"

    }


    Will print out:

    {{{}} {}}

    Question 2: Why is that's so?

    --
    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...@googlegroups.com <javascript:>.
    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.
  • Thwd at Feb 2, 2015 at 8:43 am
    post a runnable playground example at play.golang.org

    --
    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.
  • Dc0d at Feb 2, 2015 at 9:07 am
    Disclaimer: It's most likely that I'm missing something or I'm wrong as a
    Noob (& OOly corrupted mind), but I've failed to rationalize this.

    Line of Thought:

    Mixins can be implemented in Go (1.4.1) using embedding and since
    `struct{}` occupies no memory (as I understand) it fits for the situations
    that we want to add some functionality or just add a method to a type that
    may actually has nothing to do with it's state, but we like to avoid
    `CleanThing` or `ParseThing` and instead write `thing.Parse()`.

    So having:

    type X struct{}

    func (x X) F() {
         fmt.Println("functionality in X.F()")
    }

    type Y struct{ X }
    type Z struct{ Y }

    Then if we do:

    var z Z
    z.F()

    Will give us:

    functionality in X.F()

    So far so good.

    Now let's add another type `OX` with method `F()` and embed it in `Z`:

    type Z struct {
         Y
         OX
    }

    type OX struct{} // overriding X

    func (x OX) F() {
         fmt.Println("functionality in OX.F()")
    }

    Interesting! Now we get `functionality in OX.F()` which shows us that Go
    compiler searches for the method, starting from type it self and then the
    last embedded type. We can check that by adding `F()` to `Z`:

    func (x Z) F() {
         fmt.Println("functionality in Z.F()")
    }

    The output is `functionality in Z.F()`. Now if we remove the `Z.F()` method
    and add `F()` to `Y`:

    //func (x Z) F() {
    // fmt.Println("functionality in Z.F()")
    //}

    func (x Y) F() {
         fmt.Println("functionality in Y.F()")
    }

    Then we see this error `ambiguous selector z.F`; redirecting via pointers
    makes no difference.

    Question 1: Why that's so?

    The extra level of indirection `Y` meant for something else, but brought me
    to this. And as I've guessed `func (t T) String() string{}` is an
    exception. This code:

    type X struct{}

    func (x X) String() string {
         return "in X.String()"
    }

    type Y struct{ X }
    type Z struct {
         Y
         OX
    }

    type OX struct{} // overriding X

    func (x OX) String() string {
         return "in OX.String()"
    }

    func (x Y) String() string {
         return "in Y.String()"
    }

    And then this:

    var z Z
    fmt.Println(z)

    Gives us:

    {in Y.String() in OX.String()}

    Which is logical. But if we use pointer receivers:

    import (
         "fmt"
         "testing"
    )

    func TestIt(t *testing.T) {
         var z Z
         fmt.Println(z)
    }

    type X struct{}

    func (x *X) String() string {
         return "in X.String()"
    }

    type Y struct{ X }
    type Z struct {
         Y
         OX
    }

    type OX struct{} // overriding X

    func (x *OX) String() string {
         return "in OX.String()"
    }

    func (x *Y) String() string {
         return "in Y.String()"
    }

    Will print out:

    {{{}} {}}

    Question 2: Why is that's so?

    --
    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.
  • Dc0d at Feb 2, 2015 at 12:25 pm
    Please delete this thread.
    On Monday, February 2, 2015 at 12:37:22 PM UTC+3:30, dc0d wrote:

    Disclaimer: It's most likely that I'm missing something or I'm wrong as a
    Noob (& OOly corrupted mind), but I've failed to rationalize this.

    Line of Thought:

    Mixins can be implemented in Go (1.4.1) using embedding and since
    `struct{}` occupies no memory (as I understand) it fits for the situations
    that we want to add some functionality or just add a method to a type that
    may actually has nothing to do with it's state, but we like to avoid
    `CleanThing` or `ParseThing` and instead write `thing.Parse()`.

    So having:

    type X struct{}

    func (x X) F() {
    fmt.Println("functionality in X.F()")
    }

    type Y struct{ X }
    type Z struct{ Y }

    Then if we do:

    var z Z
    z.F()

    Will give us:

    functionality in X.F()

    So far so good.

    Now let's add another type `OX` with method `F()` and embed it in `Z`:

    type Z struct {
    Y
    OX
    }

    type OX struct{} // overriding X

    func (x OX) F() {
    fmt.Println("functionality in OX.F()")
    }

    Interesting! Now we get `functionality in OX.F()` which shows us that Go
    compiler searches for the method, starting from type it self and then the
    last embedded type. We can check that by adding `F()` to `Z`:

    func (x Z) F() {
    fmt.Println("functionality in Z.F()")
    }

    The output is `functionality in Z.F()`. Now if we remove the `Z.F()`
    method and add `F()` to `Y`:

    //func (x Z) F() {
    // fmt.Println("functionality in Z.F()")
    //}

    func (x Y) F() {
    fmt.Println("functionality in Y.F()")
    }

    Then we see this error `ambiguous selector z.F`; redirecting via pointers
    makes no difference.

    Question 1: Why that's so?

    The extra level of indirection `Y` meant for something else, but brought
    me to this. And as I've guessed `func (t T) String() string{}` is an
    exception. This code:

    type X struct{}

    func (x X) String() string {
    return "in X.String()"
    }

    type Y struct{ X }
    type Z struct {
    Y
    OX
    }

    type OX struct{} // overriding X

    func (x OX) String() string {
    return "in OX.String()"
    }

    func (x Y) String() string {
    return "in Y.String()"
    }

    And then this:

    var z Z
    fmt.Println(z)

    Gives us:

    {in Y.String() in OX.String()}

    Which is logical. But if we use pointer receivers:

    import (
    "fmt"
    "testing"
    )

    func TestIt(t *testing.T) {
    var z Z
    fmt.Println(z)
    }

    type X struct{}

    func (x *X) String() string {
    return "in X.String()"
    }

    type Y struct{ X }
    type Z struct {
    Y
    OX
    }

    type OX struct{} // overriding X

    func (x *OX) String() string {
    return "in OX.String()"
    }

    func (x *Y) String() string {
    return "in Y.String()"
    }

    Will print out:

    {{{}} {}}

    Question 2: Why is that's so?
    --
    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
postedFeb 2, '15 at 8:24a
activeFeb 2, '15 at 12:25p
posts6
users3
websitegolang.org

3 users in discussion

Dc0d: 4 posts Thwd: 1 post Justin Israel: 1 post

People

Translate

site design / logo © 2022 Grokbase