Go では、メソッド内のポインタ レシーバを使用して、構造体の元の値を変更できます。ただし、これは単純型には当てはまりません。この質問では、そのような変更が機能しない理由を詳しく調べ、解決策を示します。
次のコードを考えてみましょう:
package main import ( "fmt" "strconv" ) type FooInt int func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) tmp := FooInt(num) fi = &tmp } func main() { var fi *FooInt fi.FromString("5") fmt.Printf("%v\n", fi) // Prints <nil> }
ここでは、関数 FromString が期待されます。 fi の値を 5 に設定します。しかし、nil を示す
Go では、レシーバーを含む関数/メソッドの引数は元の値のコピーです。その結果、関数内の変更はコピーにのみ影響します。
ポインターの場合でも、受信側は実際のポインター自体ではなく、元のポインターのコピーです。したがって、受信者の値に加えられた変更は、元のポインタには影響しません。
これを解決するには、いくつかのオプションがあります。
変更されたものを返すポインタ:
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.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
ポインタを渡す変更:
func (fi *FooInt) FromString(i string, p **FooInt) { num, _ := strconv.Atoi(i) tmp := FooInt(num) *p = &tmp } func main() { var fi *FooInt fi.FromString("5", &fi) fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
Nil でないことを確認するレシーバー:
func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) *fi = FooInt(num) } func main() { fi := new(FooInt) // Initialize to non-nil fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
これらのソリューションのいずれかを採用すると、ポインター レシーバーを使用して単純型の値を効果的に変更できます。
以上がGo でポインター レシーバーを使用して単純型の値を変更できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。