ホームページ >バックエンド開発 >Golang >構造体を返す Go 関数の型をインターフェイスの実装にどのように使用できますか?

構造体を返す Go 関数の型をインターフェイスの実装にどのように使用できますか?

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-12-05 09:12:14982ブラウズ

How Can Go Function Types Returning Structs Be Used for Interface Implementations?

インターフェイス実装の構造体を返す 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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。