Limitations on methods, part 3
August 30, 2023
This is part 3 of 3 of a mini-series on method limitations. If you missed the earlier installations, here are links to part 1 and part 2.
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.
And now for the conclusion:
A receiver base type must be defined in the same package as the method.
This rule often confuses people coming from object-oriented languages, who want to extend an existing type with their own custom methods. Let’s first consider an example that violates the rule:
package person
type Person struct {
Name string
}
Then in another package:
package employee
import "example.com/person"
func (p person.Person) Hire() error { // syntax error: non-declaration statement outside function body
/* ... */
}
So how do you extend a type defined in another package?
Well, in short: You don’t.
At least not in the same way you may be accustomed to in classically object-oriented languages. There is no subclassing in Go. There is, however, embedding. And we can think of embedding as a way to extend a type. But it requires creating a new type. Let’s make the above example work, by modifying only our employee
package:
package employee
import "example.com/person"
type Employee struct {
person.Person // Embed the person.Person type
}
func (e Employee) Hire() error { // Now this is valid
/* ... */
}
Now one thing to be aware of here: The embedded person.Person
struct has no concept, idea, or inclination that it’s part of some other type. There is no way within a method defined on person.Person
to detect that the instance is a member of an employee.Employee
struct, as there often is in some OO languages.
Getting around this “limitation” requires an architectural redesign, which I would be happy to discuss if you find this is tripping you up. It would be best discussed over real code, so perhaps a good discussion for a future live stream. If this is something you’d like to see, send me a message and let me know!
Quotes from The Go Programming Language Specification Version of August 2, 2023