package main
import "math"
//在 Go 语言中 interface resolution 是隐式的。如果传入的类型匹配接口需要的,则编译正确。
//Shape is implemented by anything that can tell us its Area
type Shape interface {
Area() float64
}
//Rectangle has the dimensions of a rectangle
type Rectangle struct {
Width float64
Height float64
}
//方法和函数很相似,但是方法是通过一个特定类型的实例调用的。
//函数可以随时被调用,比如Perimeter(rectangle Rectangle)。不像方法需要在某个事物上调用。
//声明方法的语法跟函数差不多,因为他们本身就很相似。唯一的不同是方法接收者的语法 func(receiverName ReceiverType) MethodName(args)。
//当方法被这种类型的变量调用时,数据的引用,通过变量 receiverName 获得。在其他许多编程语言中这些被隐藏起来并且通过 this 来获得接收者。
//把类型的第一个字母作为接收者变量是 Go 语言的一个惯例。 例如:r Rectangle
//Area returns the area of the rectangle
func (r Rectangle) Area() float64 {
return r.Width * r.Height
}
//Perimeter returns the perimeter of the rectangle
func Perimeter(rectangle Rectangle) float64 {
return 2 * (rectangle.Width + rectangle.Height)
}
//Circle represents a circle...
type Circle struct {
Radius float64
}
//Area returns the ares of the circle
func (c Circle) Area() float64 {
return math.Pi * c.Radius * c.Radius
}
//Triangle represents the dimensions of a triangle
type Triangle struct {
Base float64
Height float64
}
//Area returns the area of the triangle
func (t Triangle) Area() float64 {
return (t.Base * t.Height) * 0.5
}
package main
import "testing"
func TestPerimeter(t *testing.T) {
rectangle := Rectangle{10.0, 10.0}
got := Perimeter(rectangle)
want := 40.0
if got != want {
t.Errorf("got %.2f want %.2f", got, want)
}
}
func TestArea(t *testing.T) {
areaTests := []struct {
name string
shape Shape
hasArea float64
}{
{name: "Rectangle", shape: Rectangle{Width: 12, Height: 6}, hasArea: 72.0},
{name: "Circle", shape: Circle{Radius: 10}, hasArea: 314.1592653589793},
{name: "Triangle", shape: Triangle{Base: 12, Height: 6}, hasArea: 36.0},
}
for _, tt := range areaTests {
got := tt.shape.Area()
if got != tt.hasArea {
t.Errorf("got %.2f want %.2f", got, tt.hasArea)
}
}
}
网友评论