Perimeter(width float64, height float64)
関数を記述できます。 ここで、 float64
は 123.45
のような浮動小数点数用です。f
は float64
用で、 .2
は小数点以下2桁を出力することを意味します。./shapes_test.go:6:9: undefined: Perimeter
shapes_test.go:10: got 0.00 want 40.00
.Area(width, height float64)
と呼ばれる関数を作成しましょう。RectangleArea
のように、より具体的な名前を関数に付けることができます。より適切なソリューションは、この概念をカプセル化するRectangle
と呼ばれる独自の型を定義することです。float64
ではなく、Rectangle
を使用するようにテストをリファクタリングしましょう。myStruct.field
の構文で構造体のフィールドにアクセスできます。Rectangle
を関数に渡すと、意図がより明確に伝わるが、構造体を使用することで得られるメリットが増えることに同意していただければ幸いです。Area
関数を記述することです。f
は g
に置き換えられています。f
を使用すると、正確な10進数を知るのが難しい場合があります。g
を使用すると、エラーメッセージで完全な10進数が表示されます。(fmt options)../shapes_test.go:28:13: undefined: Circle
Circle
タイプを定義する必要があります。./shapes_test.go:29:14: cannot use circle (type Circle) as type Rectangle in argument to Area
./shapes.go:20:32: Area redeclared in this block
packages
で宣言することができます。新しいパッケージで Area(Circle)
を作成することはできますが、ここではやりすぎだと感じます。t.Errorf
を呼び出すときは、t
(testing.T
)のインスタンスでメソッドErrorf
を呼び出しています。Area(rectangle)
など、好きな場所で関数を呼び出すことができる場所では、「もの」のメソッドのみを呼び出すことができます。タイプCircleにはフィールドまたはメソッドエリアがありません(type Circle has no field or method Area)
func (receiverName ReceiverType) MethodName(args)
の構文です。receiverName
変数を介してそのデータへの参照が取得されます。他の多くのプログラミング言語では、これは暗黙的に行われ、 this
を介してレシーバーにアクセスします。Area
関数を渡すために、math
パッケージから Pi
定数を借ります(インポートすることを忘れないでください\)。shapes
のコレクションを取得し、それらの Area()
メソッドを呼び出して、結果を確認することだけです。Rectangle
と Circle
の両方を渡すことができるある種の checkArea
関数を記述できるようにしたいが、形状ではないものを渡そうとするとコンパイルに失敗します。Shape
が渡されるように要求しています。これを形状ではないもので呼び出そうとすると、コンパイルされません。Shape
がインターフェース宣言を使用しているものをGoに伝えるだけですRectangle
と Circle
で行ったように新しい type
を作成していますが、今回はstruct
ではなく interface
です。My type Foo implements interface Bar
と言うコードを書く必要があります。Rectangle
にはArea
というメソッドがあり、 float64
を返すため、Shape
インターフェースを満たしますCircle
には Area
というメソッドがあり、 float64
を返すため、Shape
インターフェースを満たしますstring
にはそのようなメソッドがないため、インターフェースを満たしていませんRectangle
、Circle
、または Triangle
のどちらであるかを気にする必要がないことに注意してください。 インターフェースを宣言することにより、ヘルパーは具象型から切り離(Decoupling)され、その機能を実行するために必要なメソッドのみを持ちます。areaTests
を作成することです。 2つのフィールド、 shape
と want
で []struct
を使用して、構造体のスライスを宣言しています。次に、スライスをケースで埋めます。Area
を実装してテストケースに追加するのが非常に簡単であることを確認できます。 さらに、Area
でバグが見つかった場合、修正する前に新しいテストケースを追加して実行するのは非常に簡単です。{Triangle{12, 6}, 36.0},
を追加するだけです。./shapes_test.go:25:4: undefined: Triangle
Area()
メソッドがないため、形状として使用できないので、テストを機能させるために空の実装を追加しますshapes_test.go:31: got 0.00 want 36.00
MyStruct{val1、val2}
構造体のインスタンスを作成するための構文だけを示してきましたが、オプションでフィールドに名前を付けることができます。テストは、それが真実の主張であるかのように、より明確に私たちに話しかけます。一連の操作ではありません
Triangle
を実装していて、失敗したテストがあったことを覚えていますか?shapes_test.go:31: got 0.00 want 36.00
と表示されました。Triangle
に関連していることはわかっていましたが、それを扱っているだけでしたが、表の20のケースのいずれかでバグがシステムに侵入した場合はどうなりますか? 開発者はどのケースが失敗したかをどのようにして知るのでしょうか? これは開発者にとって素晴らしい経験ではありません。%#v got %.2f want %.2f
に変更できます。 %#v
形式の文字列は、フィールドの値を含む構造体を出力するため、開発者はテストされているプロパティを一目で確認できます。want
フィールドの名前をhasArea
のようなわかりやすい名前に変更できます。t.Run
を使用してテストケースに名前を付けることです。t.Run
でラップすることで、ケースの名前が出力されるため、失敗時のテスト出力がより明確になります。go test -run TestArea/Rectangle
を使用して、テーブル内で特定のテストを実行できます。尋ねる
方法を知るだけでした。everywhere
で使用される標準ライブラリで定義されたインターフェイスについて学び、独自のタイプに対してそれらを実装することにより、多くの優れた機能を非常に迅速に再利用できます。