Implementation of sort.Interface with or without pointer

1,253 views
Skip to first unread message

Borja Roux Lorenzo

unread,
Nov 30, 2013, 4:59:43 AM11/30/13
to golan...@googlegroups.com
According to the definition of sort.Interface, interface operations must be defined without a pointer.

If I define the functions with a pointer (func (x *mySortableType) Len() int{), I get an error: Len method has pointer receiver

In documentation of package "sort", I find example "Example (SortKeys)".

In this example, type "planetSorter" is defined and the functions that implement the interface use pointers in their definition: "func (s *planetSorter) Len() int".

Why does type "planetSorter" in "Example (SortKeys)" in documentation of "sort" package work? Shouldn't we receive a compilation error?

Ian Lance Taylor

unread,
Nov 30, 2013, 12:30:16 PM11/30/13
to Borja Roux Lorenzo, golang-nuts
On Sat, Nov 30, 2013 at 1:59 AM, Borja Roux Lorenzo
<borja...@gmail.com> wrote:
> According to the definition of sort.Interface, interface operations must be
> defined without a pointer.
>
> If I define the functions with a pointer (func (x *mySortableType) Len()
> int{), I get an error: Len method has pointer receiver

That error means that mySortableType is itself a pointer type. You
can not define a method on a pointer type.


> In documentation of package "sort", I find example "Example (SortKeys)".
>
> In this example, type "planetSorter" is defined and the functions that
> implement the interface use pointers in their definition: "func (s
> *planetSorter) Len() int".
>
> Why does type "planetSorter" in "Example (SortKeys)" in documentation of
> "sort" package work? Shouldn't we receive a compilation error?

planetSorter is not a pointer type.

Ian

Harald Weidner

unread,
Nov 30, 2013, 12:41:47 PM11/30/13
to golan...@googlegroups.com
Hello,

Borja Roux Lorenzo <borja...@gmail.com>:

>According to the definition of sort.Interface<http://golang.org/pkg/sort/#Interface>,
>interface operations must be defined without a pointer.

>In documentation of package "sort", I find example "*Example (SortKeys)*".
>
>In this example, type "planetSorter" is defined and the functions that
>implement the interface use pointers in their definition: "func (s
>*planetSorter) Len() int".

This just means that not planetSorter, but *planetSorter implements the
interface.

>Why does type "planetSorter" in "Example (SortKeys)" in documentation of
>"sort" package work? Shouldn't we receive a compilation error?

In this example, sort.Sort(ps) is invoked, where ps is of type
*planetSorter.

The example would also work if no pointer receivers were used, and
ps was of type planetSorter.

Moreover, it works without pointer receivers even if ps has type
*planetSorter, because the method set of a pointer type includes
the method set of the type it points to. (See
*http://golang.org/ref/spec#Method_sets )

Regarding this, the example might be considered unneccesarily complex.

Harald

Borja Roux Lorenzo

unread,
Nov 30, 2013, 1:01:45 PM11/30/13
to golan...@googlegroups.com
Hello,

Then the thing is which type implements sort.Interface: the type or the pointer type. I have created two samples to ilustrate this:
Thank you very much for your answer.

Harald Weidner

unread,
Nov 30, 2013, 1:32:33 PM11/30/13
to golan...@googlegroups.com
Hello,

Borja Roux Lorenzo <borja...@gmail.com>:

>Then the thing is which type implements sort.Interface: the type or the
>pointer type. I have created two samples to ilustrate this:
>
> - Sample with type implementing sort.Interface:
> http://play.golang.org/p/XCuv00eGbg (does not work properly because sorting
> operations are executed on a copy of the variable)
> - Sample with pointer type implementing
> sort.Interface: http://play.golang.org/p/paTLB8D5Vk

The first example is in fact useless, because the the Swap() function
operates on a copy of the original data.

In most usual cases, sorting is applied to slices. There a non-pointer
receiver does not hurt because a slice is some kind of a reference type
(in the sense that s[i], s[j] = s[j], s[i] sorts the original data, even
if s is a copy of the slice).

See http://play.golang.org/p/g7RWLiYFmi for a very simple example on
sort.Sort().

Harald

Christoph Hack

unread,
Nov 30, 2013, 1:34:55 PM11/30/13
to golan...@googlegroups.com
Hi Borja,

On Saturday, November 30, 2013 7:01:45 PM UTC+1, Borja Roux Lorenzo wrote:
Then the thing is which type implements sort.Interface:

here is my try to clarify a few things:

On Saturday, November 30, 2013 10:59:43 AM UTC+1, Borja Roux Lorenzo wrote:
According to the definition of sort.Interface, interface operations must be defined without a pointer.

An interface can be implemented by any type that has the required methods attached. This type might or might not be a pointer type.

Let's illustrate that with a short example:

type Foo interface { Foo() }

type A int
func (a A) Foo() {}

type B int
func (b *B) Foo() {}

Now, both types, A and *B implement the Foo interface, and you can pass values of both types to a function "func doFoo(f Foo)". In addition to that you can also pass values of type *A, since *A also implements the Foo interface (method calls automatically de-reference the pointer).

The point is that the type B does NOT implement the interface Foo. The (probably) sightly confusing part is maybe that this is possible:

var b B
b.Foo()

since b is addressable in this context and the method call automatically takes the address of b before calling Foo in that special case (see the language reference on "Calls"). But once you pass b as an argument it will no longer be addressable...
 
If I define the functions with a pointer (func (x *mySortableType) Len() int{), I get an error: Len method has pointer receiver

As long as you pass an *mySortableType to sort, everything should be fine. An example might be helpful here.

-christoph

Kevin Gillette

unread,
Nov 30, 2013, 5:53:48 PM11/30/13
to golan...@googlegroups.com
On Saturday, November 30, 2013 11:01:45 AM UTC-7, Borja Roux Lorenzo wrote:
A note on naming: myPointerTypeIsSortable isn't a pointer type, but `*myPointerTypeIsSortable` is. It is extremely rare in Go for the asterisk to be the first part of a type literal, and there might not be any use cases for doing so (Go even prohibits such types from having methods).
 
According to the definition of sort.Interface<http://golang.org/pkg/sort/#Interface>,
interface operations must be defined without a pointer.

The sort package documentation doesn't mention pointers anywhere. Implementations can and should use pointers if it is necessary to make modifications persist. Since slice elements are always addressable, and sort.Sort never needs to modify the slice header, there's simply no benefit to using pointer receivers on implementing slice types.
Reply all
Reply to author
Forward
0 new messages