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
- Q100Does converting a value to an interface allocate? How do interfaces affect escape analysis and performance?
- Q101What's the difference between a method value and a method expression? What does this print?
- Q103How does the "optional interface" (interface upgrade) pattern work? Give a stdlib example and its pitfall.
- Q104How do constraint interfaces in generics differ from ordinary interfaces?
- Q105Do methods carry over with
type B Avstype B = Avs embedding? What does this mean forsync.Mutex? - Q106How does
http.HandlerFuncwork? Explain the function-type adapter pattern.