Limitations on methods, part 2

August 29, 2023

Continuining from yesterday, when we started disecting this section of the spec:

Method declarations

A receiver base type cannot be a pointer or interface type and it must be defined in the same package as the method.

Today we’re tackling the second limitation:

A receiver base type cannot be an interface.

At first this might seem a bit counter-intuitive… aren’t interfaces all about methods? Well, yes, but in the other directions. Interfaces are collections of methods. But you can’t define methods on interfaces. To be explicit, this is invalid:

type foo interface {
	Foo() error
}

func (f foo) Bar() {} // invalid receiver type foo (pointer or interface type)

If you want to extend the foo interface with the Bar() method, the proper way is to extend the foo type definition:

type foo interface {
	Foo() error
	Bar()
}

Now it’s up to any types that implement this interface to define a method Bar().

Quotes from The Go Programming Language Specification Version of August 2, 2023

Share this

Related Content

Type parameters in method definitions

Yesterday we saw that when a method is defined on a generic type, the receiver must include type parameters. Now for all the relevant details: Method declarations … … Syntactically, this type parameter declaration looks like an instantiation of the receiver base type: the type arguments must be identifiers denoting the type parameters being declared, one for each type parameter of the receiver base type. The type parameter names do not need to match their corresponding parameter names in the receiver base type definition, and all non-blank parameter names must be unique in the receiver parameter section and the method signature.

Defining method sets

Recall that every type in Go has a method set. Let’s examine how that’s defined: Method sets … Every type has a (possibly empty) method set associated with it: The method set of a defined type T consists of all methods declared with receiver type T. type S struct { /* Possibly some fields */ } // Foo() is a member of the method set of `S`, because it has a receiver type `S`.

Implementing interfaces

Basic interfaces … More than one type may implement an interface. For instance, if two types S1 and S2 have the method set func (p T) Read(p []byte) (n int, err error) func (p T) Write(p []byte) (n int, err error) func (p T) Close() error (where T stands for either S1 or S2) then the File interface is implemented by both S1 and S2, regardless of what other methods S1 and S2 may have or share.