[]T is not []I

It’s bothered me for a while now that in Go I can’t assign a []T to an []I, where T is a concrete type implementing the I interface. But recently I learned of a very good reason. Consider this code:

type Shape interface {
	Area() int
}

type Circle interface {
	Area() int
	Radius() int
}

type Square interface {
	Area() int
	Width() int
	Height() int
}

func main() {
	var circles []Circle = getCircles()

	AddShapeToCollection(circles)

	for _, circle := range circles {
		r := circle.Radius()
		print(r)
	}
}

fund AddShapeToCollection(shapes []Shape) {
	var square Square = getSquare()
	append(shapes, square)
}

What is the “correct” behavior here? If we want to keep type safety, there is none. The only sane option is to realize a []Circle is not a []Square.

Apr 1 2012