ホームページ > バックエンド開発 > Golang > Go でポインター レシーバーを使用して単純型の値を変更できないのはなぜですか?

Go でポインター レシーバーを使用して単純型の値を変更できないのはなぜですか?

Barbara Streisand
リリース: 2024-11-16 06:53:03
オリジナル
305 人が閲覧しました

Why Can't I Modify a Simple Type's Value Using a Pointer Receiver in Go?

Go でポインタ レシーバを介して単純型の値を変更する方法?

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 を示す が出力されます。 pointer.

動作を理解する

Go では、レシーバーを含む関数/メソッドの引数は元の値のコピーです。その結果、関数内の変更はコピーにのみ影響します。

ポインターの場合でも、受信側は実際のポインター自体ではなく、元のポインターのコピーです。したがって、受信者の値に加えられた変更は、元のポインタには影響しません。

解決策

これを解決するには、いくつかのオプションがあります。

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

    • 変更されたポインタを返すように関数を変更し、それを元のポインタに割り当てます。
    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
    }
    ログイン後にコピー
  2. ポインタを渡す変更:

    • 目的の型の非 nil ポインターを関数に渡し、その値を変更します。
    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
    }
    ログイン後にコピー
  3. Nil でないことを確認するレシーバー:

    • メソッドを呼び出す前にレシーバーを非 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 サイトの他の関連記事を参照してください。

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