インターフェイス実装の構造体を返す Go 関数の型
時間のかかるメソッドとファクトリを含むパッケージ内に構造体があるシナリオを考えてみましょう関数。この構造体を効果的にテストするには、偽のファクトリ関数と作成された偽の構造体の両方を利用することが望ましいです。
次のコードはこれを例にしています:
package expensive import "fmt" type myStruct struct{} func (m *myStruct) DoSomething() { fmt.Println("In Do something") } func (m *myStruct) DoSomethingElse() { fmt.Println("In Do something else") } // CreateInstance is expensive to call func CreateInstance() *myStruct { return &myStruct{} }
依存パッケージでは、次のように:
package main import "play/expensive" func main() { thing := structToConstruct{expensive.CreateInstance} thing.performAction() } type myInterface interface { DoSomething() } type structToConstruct struct { factoryFunction func() myInterface } func (s *structToConstruct) performAction() { instance := s.factoryFunction() instance.DoSomething() }
ただし、このコードではエラー:
.\main.go:6: cannot use expensive.CreateInstance (type func() *expensive.myStruct) as type func() myInterface in field value
myInterface を実装している *expensive.myStruct にもかかわらず、Go はタイプ セーフについて不平を言います。
Go チームによると、この動作は意図的です:
Having a function type in a struct field that returns the underlying concrete type would violate a core principle of interfaces. That principle is that the concrete type can be replaced by any other implementation of the interface type. If the receiver type of a function were the underlying concrete type, the behavior of the function would change if called via an interface.
解決策は、ファクトリ関数をラップすることです:
wrapper := func() myInterface { return expensive.CreateInstance() } thing := structToConstruct{wrapper}
これラッパーは myInterface に準拠し、コードはコンパイルされます。
以上が構造体を返す Go 関数の型をインターフェイスの実装にどのように使用できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。