私が書いているおもちゃのパッケージの仕様を書いています。仕様のほとんどは、パッケージ内のさまざまな構造体がプライマリ パブリック インターフェイスを満たすことを保証していますが、インターフェイスが必要とするメソッドを指定することにも関心があります。私はこれが少し衒学的である以上のものであることを知っていますが、それはきちんとした実験であり、パブリックインターフェースを安定に保つために圧力をかけるだろうと考えました.
これは私の最初の試みです:
type Roller interface {
Min() int
}
type minS struct {}
func (m minS) Min() int {return 0}
func (m minS) Max() int {return 0}
func RollerSpec(c gospec.Context) {
var r Roller = minS{}
c.Specify("has a minimum value.", func() {
_, ok := r.(interface{Min() int})
c.Expect(ok, Equals, true)
})
c.Specify("has a maximum value.", func() {
_, ok := r.(interface{Max() int})
c.Expect(ok, Equals, true)
})
c.Specify("has an expected value.", func() {
_, ok := r.(interface{Exp() int})
c.Expect(ok, Equals, true)
})
c.Specify("can be rolled.", func() {
_, ok := r.(interface{Roll() int})
c.Expect(ok, Equals, true)
})
}
ご覧のとおり、私のRoller
インターフェイスは との両方を必要としますMin()
がminS
実装しています。最初の 2 つの仕様には合格しましたが、テストに使用したダミー型が満足しているため満足していません。同様に、基本型なしで r を宣言すると、すべての仕様に失敗します。Min()
Max()
Runner
interface{Max() int}
Go がインターフェイス間の型アサーションを実際の格納された型で機能させる理由は明らかですが、ここで探しているのはそれではありません。Reflectパッケージもチェックしましたが、構造体のみを検査しているようです。インターフェイスが特定のメソッドを必要とするかどうかをプログラムでチェックする方法はありますか?