invalid receiver type []Bleh

4,700 views
Skip to first unread message

bryanturley

unread,
Dec 5, 2012, 1:59:11 PM12/5/12
to golan...@googlegroups.com
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

Jeremy Wall

unread,
Dec 5, 2012, 2:05:03 PM12/5/12
to bryanturley, golang-nuts
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.
> --
>
>

bryanturley

unread,
Dec 5, 2012, 2:10:51 PM12/5/12
to golan...@googlegroups.com, bryanturley
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

unread,
Dec 5, 2012, 2:20:42 PM12/5/12
to bryanturley, golan...@googlegroups.com
On Wed, Dec 5, 2012 at 4:59 PM, bryanturley <bryan...@gmail.com> 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

unread,
Dec 5, 2012, 2:31:10 PM12/5/12
to golan...@googlegroups.com, bryanturley


On Wednesday, December 5, 2012 1:20:42 PM UTC-6, André Moraes wrote:
On Wed, Dec 5, 2012 at 4:59 PM, bryanturley <bryan...@gmail.com> 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

unread,
Dec 5, 2012, 2:38:28 PM12/5/12
to bryanturley, golang-nuts
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.
> --
>
>

bryanturley

unread,
Dec 5, 2012, 2:46:51 PM12/5/12
to golan...@googlegroups.com
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...

Rodrigo Kochenburger

unread,
Dec 5, 2012, 3:17:03 PM12/5/12
to golan...@googlegroups.com, bryanturley
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.

André Moraes

unread,
Dec 6, 2012, 6:33:32 AM12/6/12
to bryanturley, golan...@googlegroups.com
>
> 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.

Jan Mercl

unread,
Dec 6, 2012, 6:38:13 AM12/6/12
to André Moraes, bryanturley, golang-nuts
On Thu, Dec 6, 2012 at 12:33 PM, André Moraes <and...@gmail.com> 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

unread,
Dec 6, 2012, 8:25:40 AM12/6/12
to Jan Mercl, bryanturley, golang-nuts
>> 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. :)

Jan Mercl

unread,
Dec 6, 2012, 8:29:17 AM12/6/12
to André Moraes, bryanturley, golang-nuts
On Thu, Dec 6, 2012 at 2:25 PM, André Moraes <and...@gmail.com> 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

bryanturley

unread,
Dec 6, 2012, 2:20:06 PM12/6/12
to golan...@googlegroups.com
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.

Reply all
Reply to author
Forward
0 new messages