構造体、メソッド、インターフェース
Structs, methods & interfaces
高さと幅を指定して長方形の周囲を計算するために、いくつかのジオメトリコードが必要だとします。
Perimeter(width float64, height float64)
関数を記述できます。 ここで、 float64
は 123.45
のような浮動小数点数用です。テスト駆動開発(TDD)のサイクルはもうお馴染みのものになっているはずです。
func TestPerimeter(t *testing.T) {
got := Perimeter(10.0, 10.0)
want := 40.0
if got != want {
t.Errorf("got %.2f want %.2f", got, want)
}
}
新しいフォーマット文字列に注目してください。
f
は float64
用で、 .2
は小数点以下2桁を出力することを意味します。./shapes_test.go:6:9: undefined: Perimeter
func Perimeter(width float64, height float64) float64 {
return 0
}
Results in
shapes_test.go:10: got 0.00 want 40.00
.func Perimeter(width float64, height float64) float64 {
return 2 * (width + height)
}
これまでのところ、とても簡単です。長方形の面積を返す
Area(width, height float64)
と呼ばれる関数を作成しましょう。TDDサイクルに従って、自分で試してください。
おそらく、あなたはこのようなテストで終わるはずでしょう
func TestPerimeter(t *testing.T) {
got := Perimeter(10.0, 10.0)
want := 40.0
if got != want {
t.Errorf("got %.2f want %.2f", got, want)
}
}
func TestArea(t *testing.T) {
got := Area(12.0, 6.0)
want := 72.0
if got != want {
t.Errorf("got %.2f want %.2f", got, want)
}
}
そして、このようなコード
func Perimeter(width float64, height float64) float64 {
return 2 * (width + height)
}
func Area(width float64, height float64) float64 {
return width * height
}
私たちのコードはその役割を果たしますが、四角形について明示的なものは何も含まれていません。不注意な開発者は、三角形の幅と高さを間違った答えを返すことに気付かずにこれらの関数に提供しようとする場合があります。
RectangleArea
のように、より具体的な名前を関数に付けることができます。より適切なソリューションは、この概念をカプセル化するRectangle
と呼ばれる独自の型を定義することです。このような構造体を宣言します
type Rectangle struct {
Width float64
Height float64
}
では、プレーンな
float64
ではなく、Rectangle
を使用するようにテストをリファクタリングしましょう。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) {
rectangle := Rectangle{12.0, 6.0}
got := Area(rectangle)
want := 72.0
if got != want {
t.Errorf("got %.2f want %.2f", got, want)
}
}
修正を試みる前に必ずテストを実行してください。 次のような有用なエラーが表示されるはずです。
./shapes_test.go:7:18: not enough arguments in call to Perimeter
have (Rectangle)
want (float64, float64)
myStruct.field
の構文で構造体のフィールドにアクセスできます。2つの関数を変更してテストを修正します。
func Perimeter(rectangle Rectangle) float64 {
return 2 * (rectangle.Width + rectangle.Height)
}
func Area(rectangle Rectangle) float64 {
return rectangle.Width * rectangle.Height
}
Rectangle
を関数に渡すと、意図がより明確に伝わるが、構造体を使用することで得られるメリットが増えることに同意していただければ幸いです。次の要件は、サークルの
Area
関数を記述することです。