Go 文字列は不変です。つまり、バイト スライスへの変換にはメモリ コピーが必要です。これは、大規模なデータセットを操作する場合のパフォーマンスに影響を与える可能性があります。この記事では、重要な側面と制限を強調しながら、unsafe を使用してこのコピー操作を回避する方法について説明します。
標準ライブラリ関数 []byte(s) は、文字列 s のコピーを作成します。 。メモリ消費が懸念される場合は、このオーバーヘッドを発生させずにバイト スライスを取得することが望ましいです。
安全でないパッケージを使用すると、この目標を達成する方法が提供されます。文字列値をバイト配列へのポインタにキャストすることで、コピーを作成せずに基になるバイト スライスにアクセスできます。
<code class="go">func unsafeGetBytes(s string) []byte { return (*[0x7fff0000]byte)(unsafe.Pointer( (*reflect.StringHeader)(unsafe.Pointer(&s)).Data), )[:len(s):len(s)] }</code>
このアプローチは次のことに注意することが重要です。本質的なリスクを伴います。 Go の文字列は不変であるため、unsafeGetBytes を通じて取得したバイト スライスを変更すると、予期しない動作が発生したり、データが破損したりする可能性があります。したがって、この手法は、メモリのパフォーマンスが最優先される、制御された内部環境でのみ使用する必要があります。
空の文字列 ("") にはバイトがないので、そのデータ フィールドに注意してください。は不定です。コードで空の文字列が発生する可能性がある場合は、空の文字列を明示的にチェックすることが重要です。
<code class="go">func unsafeGetBytes(s string) []byte { if s == "" { return nil // or []byte{} } return (*[0x7fff0000]byte)(unsafe.Pointer( (*reflect.StringHeader)(unsafe.Pointer(&s)).Data), )[:len(s):len(s)] }</code>
この変換によりコピーのオーバーヘッドが回避されますが、圧縮されることを念頭に置くことが重要です。 gzipWriter を使用して前述したような操作は、大量の計算を必要とします。メモリ コピーの回避による潜在的なパフォーマンスの向上は、圧縮に必要な計算に比べればごくわずかである可能性があります。
あるいは、io.WriteString 関数を利用して文字列を io に書き込むこともできます。コピー操作を呼び出さずに .Writer を実行します。この関数は、io.Writer に WriteString メソッドが存在するかどうかを確認し、利用可能な場合はそれを呼び出します。
さらに詳しく調べるには、次のリソースを検討してください。
以上が「unsafe」を使用してコピーせずに Go 文字列からバイト スライスを取得するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。