ホームページ  >  記事  >  バックエンド開発  >  Go で `reflect.MakeSlice` がアドレス指定できない値を返すのはなぜですか?

Go で `reflect.MakeSlice` がアドレス指定できない値を返すのはなぜですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-07 21:56:03877ブラウズ

Why Does `reflect.MakeSlice` Return an Un-addressable Value in Go?

Go でreflect.MakeSlice がアドレス指定できない値を返す理由

問題の概要

Go では、reflect.MakeSlice を使用してスライスを作成すると、アドレス指定できない値。これは、次のコード スニペットに示すように、スライス アドレスが必要な場合に問題になります。

collection.Find(bson.M{}).All(&result)

リフレクションを使用したスライスへのポインターの取得

この問題を解決するには、次の 2 つの方法があります。解決策:

1. Reflect.New() の使用

最も簡単な解決策は、reflect.New() を使用してポインターを作成することです。例:

my := &My{}

// Create a slice to begin with
myType := reflect.TypeOf(my)
slice := reflect.MakeSlice(reflect.SliceOf(myType), 10, 10)

// Create a pointer to a slice value and set it to the slice
x := reflect.New(slice.Type())
x.Elem().Set(slice)

collection.Find(bson.M{}).All(x.Interface())

2.型付きマップの使用

または、型付きマップを使用して、目的の型のスライスを作成できます。

type MyStructList map[string]*MyStruct

myMap := reflect.New(reflect.MapOf(myKey, myValue))

for _, value := range myMap.MapKeys() {
    myValue := myMap.MapIndex(value)
}

reflect.MakeSlice がアドレス指定できない値を返す理由

ローカル スタック変数 (reflect.MakeSlice によって作成された変数を含む) は Go ではアドレス指定できません。これにより、これらの変数へのポインタが意味のあるままになり、無効なメモリ位置を指さないことが保証されます。

スライスへのポインタが必要な理由

mgo API は、その反復にスライスへのポインタを必要とします。スライスに追加するとメモリが再割り当てされる可能性があるため、.All は機能します。これらの変更を呼び出し元に伝えるには、ポインターが必要です。

以上がGo で `reflect.MakeSlice` がアドレス指定できない値を返すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。