Go では、ポインター レシーバー関数を使用してレシーバー オブジェクトの値を変更できます。ただし、Go でポインターがどのように機能するかを理解することは、実装を成功させるために非常に重要です。
ポインター レシーバー メソッドを通じて単純型の値を変更しようとすると、次のような状況に遭遇する可能性があります。変更はメソッドの外部では保持されません。これは、レシーバーを含むすべてのメソッド引数がメソッドの実行内でローカルにコピーされるためです。
提供された例では、
func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) tmp := FooInt(num) fi = &tmp }
fi pointer 引数は、main 内の元の fi ポインタのコピーです。したがって、FromString メソッド内でコピーされた fi ポインターに加えられた変更は、元のポインターではなく、ローカル コピーにのみ影響します。
これを解決するには、いくつかのオプションがあります。
更新されたポインターをレシーバーに割り当てる return ステートメントを作成し、返されたポインターを main で再割り当てします。
// Return the updated pointer and reassign it in main func (fi *FooInt) FromString(i string) *FooInt { num, _ := strconv.Atoi(i) tmp := FooInt(num) return &tmp } // Reassign the updated pointer in main func main() { var fi *FooInt fi = fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Outputs: 0xc0000b4020 5 }
ターゲット型の非 nil ポインタを引数としてメソッドに渡します。
// Pass a non-nil pointer as an argument func (fi *FooInt) FromString(i string, p **FooInt) { num, _ := strconv.Atoi(i) tmp := FooInt(num) *p = &tmp } // Create a non-nil pointer and pass it to the method in main func main() { var fi *FooInt fi.FromString("5", &fi) fmt.Printf("%v %v\n", fi, *fi) // Outputs: 0xc0000b4020 5 }
受信機ポインタが変更する前は nil 以外にしてください。
// Check if the receiver is non-nil before modifying func (fi *FooInt) FromString(i string) { if fi == nil { return } num, _ := strconv.Atoi(i) *fi = FooInt(num) } // Create a non-nil receiver in main func main() { fi := new(FooInt) fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Outputs: 0xc0000b4020 5 }
以上がGo でポインタ レシーバ メソッドを介して値を変更するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。