Golang で配列ポインターから配列またはスライスを作成する
Golang で、unsafe を使用して配列ポインターから配列またはスライスを作成します。 memcpy や Reflect.SliceHeader などの従来のメソッドではメモリ コピーが発生するため、ポインタは困難な場合があります。この問題に対処するために、代替アプローチについて説明します。
前書き:
解決策を詳しく調べる前に、uintptr 値を使用しても元の配列が妨げられるわけではないことに注意することが重要です。ガベージコレクションから。したがって、このような値を扱うときは注意し、アクセスする前にその有効性を確認することが重要です。さらに、Go の型安全メカニズムを優先して、安全でないパッケージの使用を制限することを強くお勧めします。
reflect.SliceHeader を使用した解決策:
効果的な方法の 1 つは、reflect を操作することです。目的の配列を指すスライス変数の .SliceHeader 記述子。これには、Data、Len、および Cap フィールドの変更が含まれます。
var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data)) sh.Data = p // Pointer to the array sh.Len = size sh.Cap = size fmt.Println(data)
これらの変更を実行すると、データ スライス変数は事実上、初期ポインタと同じ配列を指します。
複合リテラルを使用した代替ソリューション:
もう 1 つのアプローチは、複合リテラルを使用して Reflect.SliceHeader を作成することです。リテラルを取得し、スライスに変換します:
sh := &reflect.SliceHeader{ Data: p, Len: size, Cap: size, } data := *(*[]byte)(unsafe.Pointer(sh)) fmt.Println(data)
このメソッドは、前のソリューションと同じ結果を生成します。
注意事項と警告:
前述の解決策は、ポインタの使用中に元の配列がガベージ コレクションされないという前提に基づいています。ポインターの提供者がその有効性を保証することが重要です。
さらに、unsafe.Pointer のドキュメントでは、reflect.SliceHeader 構造体型の変数を直接宣言または割り当てることに対して明示的に警告しています。代わりに、実際のスライスまたは文字列を指すポインタとしてのみ使用する必要があります。
以上がメモリをコピーせずに配列ポインタから Go スライスを安全に作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。