Go

Why doesn't this compile, and why does Go refuse it?

Question 489MediumGo 1.22 to 1.25
type Shape interface{ Area() float64 }

type Square struct{ side float64 }

func (s *Square) Area() float64 { return s.side * s.side }

func main() {
    var s Shape = Square{2}  // compile error
    fmt.Println(s.Area())
}

Error: Square does not implement Shape (method Area has pointer receiver).

Method sets: the method set of T contains only value-receiver methods. The method set of *T contains both value- and pointer-receiver methods. Area has a pointer receiver, so only *Square satisfies Shape. Use var s Shape = &Square{2}.

Why: a value stored in an interface is not addressable. If Go allowed this, calling a pointer method would have to take the address of a hidden copy, and any change would silently be lost. Calling sq.Area() directly on an addressable variable sq works, because the compiler rewrites it to (&sq).Area(). The same limit explains why Square{2}.Area() on a composite literal, or on a map element, does not compile. Put var _ Shape = (*Square)(nil) near the type to get a compile-time check that it implements the interface.

More on Tricky Output & Code-Review Puzzles

All 38 Tricky Output & Code-Review Puzzles questions