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 サイトの他の関連記事を参照してください。