ホームページ  >  記事  >  バックエンド開発  >  Go でポインター レシーバー メソッドを使用して単純型を変更すると期待どおりに機能しないのはなぜですか?

Go でポインター レシーバー メソッドを使用して単純型を変更すると期待どおりに機能しないのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-16 12:29:03149ブラウズ

Why Does Modifying a Simple Type Through a Pointer Receiver Method in Go Not Work as Expected?

Go でポインター レシーバー メソッドを使用して単純な型の値を変更する方法

基本型に基づいてカスタム型を操作する場合、次のようにすることができます。ポインタ受信関数を使用して値を変更します。ただし、これを実行しようとすると、変更が無効であるように見えるシナリオに遭遇する可能性があります。詳細な説明は次のとおりです:

問題

次のコードを考えてみましょう:

package main

import "fmt"

type FooInt int

func (fi *FooInt) FromString(i string) {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    fi = &tmp // Attempting to modify the pointer
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints nil
}

このプログラムを実行すると、次のことがわかります。 FromString メソッドが変更を試みたにもかかわらず、fi の値は nil のままです。

説明

Go では、レシーバーを含むすべての関数の引数は値によって渡されます。これは、FromString メソッド内では、fi ポインターが main で宣言された実際のポインターのコピーであることを意味します。メソッド内で fi を変更すると、元のポインターではなくコピーが変更されるだけです。

この問題を解決するには、2 つのオプションがあります。

1.変更されたポインタを返す

FromString メソッドから変更されたポインタを返し、それを元のポインタに割り当てることができます:

func (fi *FooInt) FromString(i string) *FooInt {
    num, _ := strconv.Atoi(i)
    tmp := FooInt(num)
    return &tmp
}

func main() {
    var fi *FooInt
    fi = fi.FromString("5")
    fmt.Println(fi) // Prints the address of the modified pointer
}

2。レシーバーが非 nil であることを確認します

または、ポイントされた値を変更する前に、レシーバーが nil でないことを確認できます。

func (fi *FooInt) FromString(i string) {
    if fi == nil {
        fi = new(FooInt) // Initialize fi if it's nil
    }
    num, _ := strconv.Atoi(i)
    *fi = FooInt(num)
}

func main() {
    var fi *FooInt
    fi.FromString("5")
    fmt.Println(fi) // Prints the address of the modified pointer
}

これにより、レシーバーが nil でないことが保証されます。

要約すると、Go でポインター レシーバー メソッドを通じて値を変更するときは、次の点に注意してください。レシーバはコピーであり、予期しない動作を避けるために、変更されたポインタを返すか、レシーバが非 nil であることを確認する必要があります。

以上がGo でポインター レシーバー メソッドを使用して単純型を変更すると期待どおりに機能しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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