声明结构体创建我们自己的类型, 让我们把数据集合在一起并达到代码简化的目的

声明接口,这样我们可以定义适合不同参数类型的函数(参数多态)

在自己的数据类型中添加方法以实现接口

列表驱动测试让断言更清晰, 这样可以使测试文件更易于扩展和维护

结构体:
1
package main
2
3
import "math"
4
5
type Shape interface {
6
	Area() float64
7
}
8
9
type Rectangle struct {
10
	Width  float64
11
	Length float64
12
}
13
14
func (r Rectangle) Area() float64 {
15
	return r.Width * r.Length
16
}
17
18
type Circle struct {
19
	Radius float64
20
}
21
22
func (c Circle) Area() float64 {
23
	return math.Pi * c.Radius * c.Radius
24
}
25
26
type Triangle struct {
27
	Width  float64
28
	Height float64
29
}
30
31
func (t Triangle) Area() float64 {
32
	return t.Width * t.Height / 2
33
}
34
35
func Perimeter(rectangle Rectangle) float64 {
36
	return 2 * (rectangle.Length + rectangle.Width)
37
}
单元测试
1
package main
2
3
import "testing"
4
5
func TestPerimter(t *testing.T) {
6
	rectangle := Rectangle{10.0, 10.0}
7
	got := Perimeter(rectangle)
8
	want := 40.0
9
10
	if got != want {
11
		t.Errorf("got %.2f want %.2f", got, want)
12
	}
13
}
14
15
func TestArea(t *testing.T) {
16
17
	checkArea := func(t *testing.T, shape Shape, want float64) {
18
		t.Helper()
19
		got := shape.Area()
20
		if got != want {
21
			t.Errorf("got %.2f want %.2f", got, want)
22
		}
23
	}
24
25
	t.Run("rectangle", func(t *testing.T) {
26
		rectangle := Rectangle{12, 6}
27
28
		checkArea(t, rectangle, 72.0)
29
	})
30
31
	t.Run("circle", func(t *testing.T) {
32
		circle := Circle{10}
33
34
		checkArea(t, circle, 314.1592653589793)
35
	})
36
}
37
38
func TestAreaNew(t *testing.T) {
39
40
	// 表格驱动测试
41
42
	areaTests := []struct {
43
		name    string
44
		shape   Shape
45
		hasArea float64
46
	}{
47
		{name: "Rectangle", shape: Rectangle{Width: 12, Length: 6}, hasArea: 72.0},
48
		{name: "Circle", shape: Circle{Radius: 10}, hasArea: 314.1592653589793},
49
		{name: "Triangle", shape: Triangle{Width: 12, Height: 6}, hasArea: 36.0},
50
	}
51
52
	for _, tt := range areaTests {
53
		t.Run(tt.name, func(t *testing.T) {
54
			got := tt.shape.Area()
55
			if got != tt.hasArea {
56
				t.Errorf("%#v got %.2f want %.2f", tt.shape, got, tt.hasArea)
57
			}
58
		})
59
	}
60
}