FAQ
I have already worked around this tiny problem but I seek comprehension, is
this a symbol problem for the linkers?

type Bleh struct {}

func (x []Bleh) SadFace() {
// doesn't work
}
func (x *[]Bleh) WeirdFace() {
// doesn't work
}
func HappyFace(x []Bleh) {
// does work
}

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

--

Search Discussions

  • Jeremy Wall at Dec 5, 2012 at 7:05 pm
    I'm not sure if this is actually the answer but []Bleh is not a type
    you defined in this file therefore you shouldn't be allowed to set
    methods on it.

    The correct way would be:

    type BlehSlice []Bleh

    func (x BlehSlice) SadFace() {
    ...
    }

    Since BlehSlice is a type you defined you will be allowed to set methods on it.
    On Wed, Dec 5, 2012 at 12:59 PM, bryanturley wrote:
    I have already worked around this tiny problem but I seek comprehension, is
    this a symbol problem for the linkers?

    type Bleh struct {}

    func (x []Bleh) SadFace() {
    // doesn't work
    }
    func (x *[]Bleh) WeirdFace() {
    // doesn't work
    }
    func HappyFace(x []Bleh) {
    // does work
    }

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

    --
    --
  • Bryanturley at Dec 5, 2012 at 7:10 pm

    On Wednesday, December 5, 2012 1:05:03 PM UTC-6, Jeremy Wall wrote:
    I'm not sure if this is actually the answer but []Bleh is not a type
    you defined in this file therefore you shouldn't be allowed to set
    methods on it.

    The correct way would be:

    type BlehSlice []Bleh

    func (x BlehSlice) SadFace() {
    ...
    }
    That did work, what I am curious about though is why the other is invalid.
    Any case I am just doing the HappyFace bit so...

    --
  • André Moraes at Dec 5, 2012 at 7:20 pm

    On Wed, Dec 5, 2012 at 4:59 PM, bryanturley wrote:
    I have already worked around this tiny problem but I seek comprehension, is
    this a symbol problem for the linkers?

    type Bleh struct {}

    func (x []Bleh) SadFace() {
    // doesn't work
    }
    You are defining a function to the slice of Bleh. AFAIK, go can't do that.

    In order to define this function you need to

    type Bleh struct{}
    type Blehs []Bleh

    func (b Blehs) SadFace() {
    }

    func (b Blehs) HappyFace() {
    }

    See: http://play.golang.org/p/K6SylioAfZ
    func (x *[]Bleh) WeirdFace() {
    // doesn't work
    }
    func HappyFace(x []Bleh) {
    // does work
    }

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

    --


    --
    André Moraes
    http://amoraes.info

    --
  • Bryanturley at Dec 5, 2012 at 7:31 pm

    On Wednesday, December 5, 2012 1:20:42 PM UTC-6, André Moraes wrote:
    On Wed, Dec 5, 2012 at 4:59 PM, bryanturley wrote:
    I have already worked around this tiny problem but I seek comprehension, is
    this a symbol problem for the linkers?

    type Bleh struct {}

    func (x []Bleh) SadFace() {
    // doesn't work
    }
    You are defining a function to the slice of Bleh. AFAIK, go can't do that.
    Yes it was curiosity, why can't go do that?
    From what I can tell without digging to deeply.

    func (x Bleh) Q(y int) { }
    func R(x Bleh, y int) { }

    are identical except to the linker.
    I assumed the first got renamed to something like Bleh_Q in the object
    files but otherwise has the same definition as R.
    For instance function pointers of Bleh.Q look like R.

    And don't take this as another I DEMAND GO DOES THIS <RAGE><RAGE><RAGE>
    thread ;)
    I am just not defining functions on slices.

    --
  • Jeremy Wall at Dec 5, 2012 at 7:38 pm
    The reason is because it would violate the spec.

    Methods can only be added to types you own. You don't own the []Bleh
    type so you can't add methods to it. Go is very clear about who owns a
    type in the spec.

    In the case of a slice, array, map, or other builtin primitive type
    you don't own them. The Go language owns them.
    On Wed, Dec 5, 2012 at 1:31 PM, bryanturley wrote:

    On Wednesday, December 5, 2012 1:20:42 PM UTC-6, André Moraes wrote:
    On Wed, Dec 5, 2012 at 4:59 PM, bryanturley wrote:
    I have already worked around this tiny problem but I seek comprehension,
    is
    this a symbol problem for the linkers?

    type Bleh struct {}

    func (x []Bleh) SadFace() {
    // doesn't work
    }
    You are defining a function to the slice of Bleh. AFAIK, go can't do that.
    Yes it was curiosity, why can't go do that?
    From what I can tell without digging to deeply.

    func (x Bleh) Q(y int) { }
    func R(x Bleh, y int) { }

    are identical except to the linker.
    I assumed the first got renamed to something like Bleh_Q in the object files
    but otherwise has the same definition as R.
    For instance function pointers of Bleh.Q look like R.

    And don't take this as another I DEMAND GO DOES THIS <RAGE><RAGE><RAGE>
    thread ;)
    I am just not defining functions on slices.

    --
    --
  • Bryanturley at Dec 5, 2012 at 7:46 pm

    On Wednesday, December 5, 2012 1:38:28 PM UTC-6, Jeremy Wall wrote:
    The reason is because it would violate the spec.

    Methods can only be added to types you own. You don't own the []Bleh
    type so you can't add methods to it. Go is very clear about who owns a
    type in the spec.

    In the case of a slice, array, map, or other builtin primitive type
    you don't own them. The Go language owns them.
    Yes, I guess I was seeing it as more of a grey thing, possibly from to much
    c code in my life...
    Just as I didn't define *Bleh only Bleh I assumed []Bleh would function in
    a similar fashion.
    But I guess * is a type attribute not a type itself so...

    --
  • André Moraes at Dec 6, 2012 at 11:33 am

    Yes, I guess I was seeing it as more of a grey thing, possibly from to much
    c code in my life...
    Just as I didn't define *Bleh only Bleh I assumed []Bleh would function in a
    similar fashion.
    But I guess * is a type attribute not a type itself so...
    Go slice's are slices, not pointers to a sequence of things stored
    side-by-side. :)

    C-> []int == *int
    Go-> []int != *int

    That's why *Bleh works, and []Bleh don't.

    In the first case, you are declaring a method with a receiver that is
    a pointer-to your owned type.

    In the second, you are declaring a method with a receiver that is a
    slice of your owned type. And, like Jeremy already explained, slices
    are types that you don't own, so you can't define types on those.

    When you write

    type Blehs []Bleh

    func (b Blehs) Method1() { ... }
    func (b Blehs) Method2() { ... }

    Your are telling to the compiler:

    I own a type that is based on a slice of Bleh and have this extra methods.


    --
    André Moraes
    http://amoraes.info

    --
  • Jan Mercl at Dec 6, 2012 at 11:38 am

    On Thu, Dec 6, 2012 at 12:33 PM, André Moraes wrote:
    Your are telling to the compiler:

    I own a type that is based on a slice of Bleh and have this extra methods.
    There's no concept of ownership of a type in the Go specs. From top of
    my head the rule is roughly: Methods can be declared only for named
    types which are (top level) declared in the same package.

    -j

    --
  • André Moraes at Dec 6, 2012 at 1:25 pm

    Your are telling to the compiler:

    I own a type that is based on a slice of Bleh and have this extra methods.
    There's no concept of ownership of a type in the Go specs. From top of
    The "own" was just a analogy to explict the difference from a
    pointer-to-type to a slice-of-type.
    Methods can be declared only for named
    types which are (top level) declared in the same package.
    In that case, you "own" the file declaring the types. :)


    --
    André Moraes
    http://amoraes.info

    --
  • Jan Mercl at Dec 6, 2012 at 1:29 pm

    On Thu, Dec 6, 2012 at 2:25 PM, André Moraes wrote:
    Your are telling to the compiler:

    I own a type that is based on a slice of Bleh and have this extra methods.
    There's no concept of ownership of a type in the Go specs. From top of
    The "own" was just a analogy to explict the difference from a
    pointer-to-type to a slice-of-type.
    Methods can be declared only for named
    types which are (top level) declared in the same package.
    `[]T` is not a named type, that's the problem. Not pointer vs non
    pointer. Given `type T = []U` one can define methods for `T` and/or
    `*T` receivers.

    -j

    --
  • Gordon Klaus at Dec 6, 2012 at 4:39 pm
    All hail the spec http://golang.org/ref/spec#Method_declarations

    The receiver type must be of the form T or *T where T is a type name. The
    type denoted by T is called the receiver *base type*; it must not be a
    pointer or interface type and it must be declared in the same package as
    the method.
    --
  • Bryanturley at Dec 6, 2012 at 7:27 pm

    On Thursday, December 6, 2012 7:29:17 AM UTC-6, Jan Mercl wrote:

    `[]T` is not a named type, that's the problem. Not pointer vs non
    pointer. Given `type T = []U` one can define methods for `T` and/or
    `*T` receivers.

    -j
    It finally clicked for me this morning.
    The problem in my head was [] isn't a type. In this case "named type".
    And []Bleh was still in my mind a local type.
    [] isn't a full type it is a hard coded generic, and since the language
    doesn't truly support generics it has some kinks surrounding it's few
    semi-generic things.
    No worries though, I love go and don't care about generics or starting
    another generics rage thread ;)

    Having to "type BlehSlice []Bleh" isn't really a big deal either.

    --
  • Rodrigo Kochenburger at Dec 5, 2012 at 8:17 pm
    I might be wrong here but I believe that is not allowed intentionally.
    Pretty much the same reason you can't define methods on types defined on
    other packages.
    On Wednesday, December 5, 2012 11:31:10 AM UTC-8, bryanturley wrote:


    On Wednesday, December 5, 2012 1:20:42 PM UTC-6, André Moraes wrote:
    On Wed, Dec 5, 2012 at 4:59 PM, bryanturley wrote:
    I have already worked around this tiny problem but I seek
    comprehension, is
    this a symbol problem for the linkers?

    type Bleh struct {}

    func (x []Bleh) SadFace() {
    // doesn't work
    }
    You are defining a function to the slice of Bleh. AFAIK, go can't do
    that.
    Yes it was curiosity, why can't go do that?
    From what I can tell without digging to deeply.

    func (x Bleh) Q(y int) { }
    func R(x Bleh, y int) { }

    are identical except to the linker.
    I assumed the first got renamed to something like Bleh_Q in the object
    files but otherwise has the same definition as R.
    For instance function pointers of Bleh.Q look like R.

    And don't take this as another I DEMAND GO DOES THIS <RAGE><RAGE><RAGE>
    thread ;)
    I am just not defining functions on slices.
    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedDec 5, '12 at 6:59p
activeDec 6, '12 at 7:27p
posts14
users6
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase