ホームページ > バックエンド開発 > Golang > Go マップ インデックスでポインター レシーバー メソッドを呼び出せないのはなぜですか?

Go マップ インデックスでポインター レシーバー メソッドを呼び出せないのはなぜですか?

Susan Sarandon
リリース: 2024-12-29 13:01:11
オリジナル
595 人が閲覧しました

Why Can't I Call a Pointer Receiver Method on a Go Map Index?

Go でのマップ インデックスの逆参照

マップ内の値を操作するときは、マップのポインター レシーバーの動作を認識することが重要ですエントリ。以下のコードに例示されているように、マップ インデックスでポインター レシーバー メソッドを呼び出そうとするときによくある落とし穴が発生します。

package main

import "fmt"

type item struct {
    itemName string
    amount   int
}

type Cashier struct {
    items map[int]item
    cash  int
}

func (i *item) GetAmount() int {
    return i.amount
}

func main() {
    x := Cashier{}
    x.AddItem("item1", 13)
    f := x.GetItems()

    fmt.Println(f[0].GetAmount()) // Error: cannot call pointer method on f[0]
}
ログイン後にコピー

このコードでは、GetAmount メソッドは項目を直接操作するポインター レシーバーとして定義されています。構造体。ただし、 f[0].GetAmount() を呼び出すと、「f[0] でポインター メソッドを呼び出すことができません」というエラーが表示されます。これは、マップが拡大または縮小するとアドレスが変更される可能性があるため、マップ エントリを直接アドレス指定できないためです。

この動作の理由は、Go がマップを実装する方法にあります。マップは内部的にハッシュ テーブルとして表され、パフォーマンスを最適化するために実行時にサイズを変更できます。その結果、マップ エントリのアドレスが時間の経過とともに変化する可能性があり、ポインタ レシーバ メソッドに引数として渡すことが無効になります。

この問題を解決するには、マップのコピーを作成することが 1 つの方法です。ポインタ レシーバを使用する代わりにエントリを追加します。これは、まずインデックスを使用してマップから値を取得し、次にその値のコピーを作成することで実現できます。

func main() {
    x := Cashier{}
    x.AddItem("item1", 13)
    f := x.GetItems()

    itemCopy := f[0]
    fmt.Println(itemCopy.GetAmount()) // No error
}
ログイン後にコピー

この場合、itemCopy は f[0] に格納されている値のコピーです。これを使用すると、エラーが発生することなくポインタ レシーバ メソッドを呼び出すことができます。

マップ エントリを使用してポインタ レシーバの動作を理解することで、開発者はこの落とし穴を回避してコードを作成できます。マップ値に対して正しく動作します。

以上がGo マップ インデックスでポインター レシーバー メソッドを呼び出せないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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