安全でない配列から配列またはスライスを効率的に初期化する方法。Go のポインター
Go の世界では、シナリオに遭遇する可能性があります。ここでは、unsafe.Pointer として表されるデータ構造を操作する必要があります。たとえば、
p := uintptr(unsafe.Pointer(&array)) size := 5
のような配列へのポインターがあるとします。ただし、ポインターは単にそのアドレスを表すものであるため、配列に直接アクセスすることは不可能です。このため、メモリ コピーに頼ることなく、既知のポインタ、サイズ、データ型を使用して配列またはスライスを作成するという課題が残ります。
配列/スライス作成に対する安全でないアプローチ
最初に、次のアプローチを検討できます:
data := make([]byte, size) stepSize := unsafe.Sizeof(data[0]) for i := 0; i < size; i++ { data[i] = *(*byte)(unsafe.Pointer(p)) p += stepSize }
この解決策は、元の配列から新しいスライスにデータをコピーします。これは、特に大規模なデータセットの場合、非効率的になる可能性があります。
reflect.SliceHeader を使用した効率的なアプローチ
より効率的な代替方法は、Go のリフレクション パッケージと反映.SliceHeader タイプ。 Reflect.SliceHeader のフィールドを直接操作することで、ポインタと同じ基になるデータを参照する配列またはスライスを作成できます。
ステップ 1:reflect.SliceHeader 記述子を取得する
スライス変数を宣言し、unsafe を使用してその []byte 型を *reflect.SliceHeader にキャストします変換:
var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data))
ステップ 2: SliceHeader フィールドを変更する
reflect.SliceHeader:
sh.Data = p sh.Len = size sh.Cap = size
ステップ 3: 元のデータに変換し直すtype
最後に、安全でない変換を使用して、変更したreflect.SliceHeaderを目的のデータ型にキャストして戻します:data = *(*[]byte)(unsafe.Pointer(sh))
以上がunsafe.Pointer から Go 配列またはスライスを効率的に作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。