Go

On which types can you declare methods? Can you add a method to int, time.Time, a pointer type, or an interface?

Question 102MediumGo 1.22 to 1.25

You can declare a method only on a defined type declared in the same package. The receiver's base type must not be a pointer type or an interface type. The base type can be a struct, slice, map, func, chan, or basic type.

// func (i int) Double() int {}          // error: cannot define new methods on non-local type int
// func (t time.Time) Pretty() string {}  // error: non-local type

type MyInt int
func (i MyInt) Double() MyInt { return i * 2 }   // OK

type Stack []int
func (s *Stack) Push(v int) { *s = append(*s, v) } // OK: methods on slice types

type HandlerFunc func(string)
func (f HandlerFunc) Handle(s string) { f(s) }     // OK: methods on func types

type IntPtr *int
// func (p IntPtr) Get() int {}          // error: invalid receiver type IntPtr (pointer or interface type)

type Shape interface{ Area() float64 }
// func (s Shape) Describe() {}          // error: invalid receiver type Shape

// To extend a foreign type: define a new type or wrap it
type Timestamp struct{ time.Time }       // keeps Time's methods via embedding

Because of this rule, no package can add methods to your types, so interface satisfaction can never change "at a distance". It also rules out Swift- or Kotlin-style extension methods. Methods on generic types cannot declare their own type parameters: func (s *Stack[T]) Map[U any]() is illegal (as of Go 1.25). Write a top-level generic function such as Map[T, U any](s Stack[T], f func(T) U) Stack[U] instead.

More on Interfaces, Methods & Embedding

All 35 Interfaces, Methods & Embedding questions