90 lines
1.7 KiB
Go
90 lines
1.7 KiB
Go
// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
|
|
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/
|
|
|
|
// See page 161.
|
|
|
|
// Coloredpoint demonstrates struct embedding.
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
)
|
|
|
|
//!+decl
|
|
import "image/color"
|
|
|
|
type Point struct{ X, Y float64 }
|
|
|
|
type ColoredPoint struct {
|
|
Point
|
|
Color color.RGBA
|
|
}
|
|
|
|
//!-decl
|
|
|
|
func (p Point) Distance(q Point) float64 {
|
|
dX := q.X - p.X
|
|
dY := q.Y - p.Y
|
|
return math.Sqrt(dX*dX + dY*dY)
|
|
}
|
|
|
|
func (p *Point) ScaleBy(factor float64) {
|
|
p.X *= factor
|
|
p.Y *= factor
|
|
}
|
|
|
|
func main() {
|
|
//!+main
|
|
red := color.RGBA{255, 0, 0, 255}
|
|
blue := color.RGBA{0, 0, 255, 255}
|
|
var p = ColoredPoint{Point{1, 1}, red}
|
|
var q = ColoredPoint{Point{5, 4}, blue}
|
|
fmt.Println(p.Distance(q.Point)) // "5"
|
|
p.ScaleBy(2)
|
|
q.ScaleBy(2)
|
|
fmt.Println(p.Distance(q.Point)) // "10"
|
|
//!-main
|
|
}
|
|
|
|
/*
|
|
//!+error
|
|
p.Distance(q) // compile error: cannot use q (ColoredPoint) as Point
|
|
//!-error
|
|
*/
|
|
|
|
func init() {
|
|
//!+methodexpr
|
|
p := Point{1, 2}
|
|
q := Point{4, 6}
|
|
|
|
distance := Point.Distance // method expression
|
|
fmt.Println(distance(p, q)) // "5"
|
|
fmt.Printf("%T\n", distance) // "func(Point, Point) float64"
|
|
|
|
scale := (*Point).ScaleBy
|
|
scale(&p, 2)
|
|
fmt.Println(p) // "{2 4}"
|
|
fmt.Printf("%T\n", scale) // "func(*Point, float64)"
|
|
//!-methodexpr
|
|
}
|
|
|
|
func init() {
|
|
red := color.RGBA{255, 0, 0, 255}
|
|
blue := color.RGBA{0, 0, 255, 255}
|
|
|
|
//!+indirect
|
|
type ColoredPoint struct {
|
|
*Point
|
|
Color color.RGBA
|
|
}
|
|
|
|
p := ColoredPoint{&Point{1, 1}, red}
|
|
q := ColoredPoint{&Point{5, 4}, blue}
|
|
fmt.Println(p.Distance(*q.Point)) // "5"
|
|
q.Point = p.Point // p and q now share the same Point
|
|
p.ScaleBy(2)
|
|
fmt.Println(*p.Point, *q.Point) // "{2 2} {2 2}"
|
|
//!-indirect
|
|
}
|