Golang で unsafe.Pointer からスライスまたは配列を作成する: 効率的な代替手段
配列へのポインタは、Golang では uintptr 値として表すことができます。ただし、ポインタが uintptr として格納されている場合、元の配列にアクセスするのは困難になる可能性があります。
非効率な方法: メモリのコピー
1 つの単純なアプローチは、データをコピーすることです。新しいスライスへのポインタ:
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
より効率的な方法は、reflect.SliceHeader を使用してスライスを作成することです。またはメモリをコピーせずに配列:
var data []byte sh := (*reflect.SliceHeader)(unsafe.Pointer(&data)) sh.Data = p sh.Len = size sh.Cap = size fmt.Println(data)
このメソッドは uintptr を.SliceHeader を反映し、そのフィールドが既存の配列を指すように変更されます。結果のスライスまたは配列は、元の配列と同じ基礎となるメモリを共有します。
代替方法: 複合リテラル
もう 1 つの代替方法は、複合リテラルを使用して、 reflect.SliceHeader:
sh := &reflect.SliceHeader{ Data: p, Len: size, Cap: size, } data := *(*[]byte)(unsafe.Pointer(sh)) fmt.Println(data)
このアプローチでは、前のアプローチと同じ結果が生成されます。 method.
注意事項
uintptr ポインターを使用する場合は、ポインターの存続期間中、元の配列が有効であることを確認することが重要です。さらに、パッケージアンセーフはタイプセーフティに影響を与える可能性があるため、慎重に使用する必要があります。
以上がunsafe.Pointer から Go スライスまたは配列を効率的に作成する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。