types4.go ========= :: // types4.go package main import ( "fmt" ) type Point struct { x, y float64 } // The method set of an interface is a the set of methods listed in it. type Rectangler interface { width() float64 height() float64 upperLeft() Point } // Rectangler ////////////////////////////////////////////////////////////////// // In the following methods, the parameter r is of interface type Rectangler, // which means any object that implements Rectangler could be passed to it. A // type T implements the Rectangler interface is the methods set of T is a // superset of the method set of Rectangle. The functions can only use methods // in the method set of r, i.e. only methods listed in Rectangler. func print(r Rectangler) { fmt.Printf("", r.upperLeft().x, r.upperLeft().y, r.width(), r.height()) } func println(r Rectangler) { print(r) fmt.Println() } func area(r Rectangler) float64 { return r.width() * r.height() } func perimeter(r Rectangler) float64 { return 2 * (r.width() * r.height()) } ////////////////////////////////////////////////////////////////// type Rect1 struct { uLeft Point lRight Point } // Rect1 func makeRect1(x, y, width, height float64) Rect1 { return Rect1{Point{x, y}, Point{x + width, y + height}} } // The method set of Rect1 is all the methods with Rect1 as a receiever, i.e. // width, height, and upperLeft. The method set of *Rect1 is all the methods // with *Rect1 or Rect1 as the receiver. There are no methods with *Rect1 as // the receiver, so the method set of *Rect1 is the same as the method set for // Rect1. func (r Rect1) width() float64 { return r.lRight.x - r.uLeft.x } func (r Rect1) height() float64 { return r.lRight.y - r.uLeft.y } func (r Rect1) upperLeft() Point { return r.uLeft } ////////////////////////////////////////////////////////////////// type Rect2 struct { uLeft Point w, h float64 } // Rect2 func makeRect2(x, y, width, height float64) Rect2 { return Rect2{Point{x, y}, width, height} } func (r Rect2) width() float64 { return r.w } func (r Rect2) height() float64 { return r.h } func (r Rect2) upperLeft() Point { return Point{r.uLeft.x + r.w, r.uLeft.y + r.h} } ////////////////////////////////////////////////////////////////// func main() { a := makeRect1(0, 0, 10, 5) b := makeRect2(0, 0, 2, 2) println(a) fmt.Printf("area=%v, perim=%v\n", area(a), perimeter(a)) println(b) fmt.Printf("area=%v, perim=%v\n", area(b), perimeter(b)) } // main