ホームページ > バックエンド開発 > Golang > Go インターフェイス実装でポインター レシーバーを使用するとポインターを返す必要があるのはなぜですか?

Go インターフェイス実装でポインター レシーバーを使用するとポインターを返す必要があるのはなぜですか?

DDD
リリース: 2024-12-12 11:35:11
オリジナル
733 人が閲覧しました

Why Does Using Pointer Receivers in Go Interface Implementations Require Returning Pointers?

Golang のポインター レシーバーとインターフェイス実装

Go では、レシーバー関数を使用してメソッドが特定の型を操作できるようにします。メソッドにポインター レシーバーがある場合、構造体の実際のインスタンスを変更できます。

問題の理解

次のコード スニペットを検討してください:

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with non-pointer receiver
func (i Implementation) GetSomeField() string {
    return i.someField
}

// Method with non-pointer receiver
func (i Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}
ログイン後にコピー

このコードでは、両方のメソッドに非ポインター レシーバーがあります。これは、SetSomeField を呼び出すと、構造体のコピーが作成され、そのコピーが変更されることを意味します。元のインスタンスは変更されません。

ポインタ レシーバの使用

実際のインスタンスを変更するには、SetSomeField メソッドにポインタ レシーバが必要です:

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}
ログイン後にコピー

SetSomeField は元のインスタンスを変更できるようになりました。ただし、これにより IFace インターフェイスを実装するときに問題が発生します。

package main

import (
    "fmt"
)

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with pointer receiver
func (i *Implementation) GetSomeField() string {
    return i.someField
}

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

func Create() IFace {
    obj := Implementation{someField: "Hello"}
    return obj // Offending line
}

func main() {
    a := Create() // Assigning an Implementation value to an IFace variable
    a.SetSomeField("World") // Will panic because a is an Implementation value, not a pointer
    fmt.Println(a.GetSomeField())
}
ログイン後にコピー

Create は実装値へのポインターではなく実装値を返すため、このコードをコンパイルするとパニックが発生します。ポインター レシーバーを使用してインターフェイスを実装するには、メソッドをポインター レシーバーとして宣言し、Create 関数が実装へのポインターを返す必要があります。

type IFace interface {
    SetSomeField(newValue string)
    GetSomeField() string
}

type Implementation struct {
    someField string
}

// Method with pointer receiver
func (i *Implementation) GetSomeField() string {
    return i.someField
}

// Method with pointer receiver
func (i *Implementation) SetSomeField(newValue string) {
    i.someField = newValue
}

func Create() *Implementation {
    obj := Implementation{someField: "Hello"}
    return &obj
}

func main() {
    var a IFace
    a = Create() // Now assigning a pointer to Implementation to an IFace variable
    a.SetSomeField("World")
    fmt.Println(a.GetSomeField())
}
ログイン後にコピー

ここで、 a は実装値へのポインターです。ポインタ レシーバを備えた IFace を実装します。 SetSomeField を通じて行われた変更は、元のインスタンスに影響します。

以上がGo インターフェイス実装でポインター レシーバーを使用するとポインターを返す必要があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート