24

stringに変換しましょう[]byte

func toBytes(s string) []byte {
  return []byte(s) // What happens here?
}

このキャスト操作はどれくらいの費用がかかりますか?コピーは実行されますか?Goの仕様で見る限り、文字列はバイトのスライスのように動作しますが、不変です。これには、後続のスライス操作で文字列が変更されないようにするために、少なくともコピーが必要sです。逆会話はどうなりますか?[]byte <-> string会話には、utf8 <->ルーンのようなエンコード/デコードが含まれますか?

4

3 に答える 3

37

[]byte(s)キャストではなく、変換です。一部の変換は、 のようuint(myIntvar)にキャストと同じで、ビットをその場で再解釈するだけです。残念ながら、これは文字列からバイト スライスへの変換には当てはまりません。バイト スライスは変更可能ですが、文字列 (正確には文字列値) は変更できません。結果は、作成中の文字列の必要なコピー (メモリ割り当て + コンテンツ転送) です。はい、一部のシナリオではコストがかかる可能性があります。

編集: エンコード変換は実行されません。文字列 (コピー元) のバイトはそのままスライス (コピー先) のバイトにコピーされます。

于 2013-01-17T06:59:38.440 に答える
13

変換によりバイトがコピーされますが、ヒープ上の [] バイトにスペースも割り当てられます。文字列を []byte に繰り返し変換する場合は、[]byte を再利用し、copy コマンドを使用することで、メモリ管理時間を節約できます。( http://golang.org/ref/spec#Appending_and_copying_slicesと、文字列をソースとして使用する特別なケースを参照してください。)

変換とコピー コマンドのどちらの場合も、コピー自体は非常に高速に実行されるストレート バイト コピーです。CPUが効率的に実行するある種の繰り返し移動命令をコンパイラが生成することを期待しています。

バイト スライスから文字列を作成する逆変換には、文字列をヒープに割り当てる必要があります。不変性のプロパティがこれを強制します。[]byte で可能な限り多くの作業を行い、最後に文字列を作成することで最適化できる場合があります。bytes.Buffer 型が役立つことがよくあります。

現在、エンコーディングと UTF-8 は問題ではありません。文字列と []byte はどちらも任意のデータを保持できます。コピーはデータを参照せず、コピーするだけです。文字列などに UTF-8 を含めることを意図している、またはこれが推奨されていることを示す場合は、慎重に言葉を選択してください。for ステートメントの範囲句など、一部の言語機能は文字列を UTF-8 として解釈することに注意してください。文字列を UTF-8 として解釈するものとそうでないものを学んでください。文字列に非 UTF-8 があり、バイト単位で範囲を指定する必要がありますか? 問題ありません。範囲句を使用しないでください。

s := "string"
for i := 0; i < len(s); i++ {
    b := s[i]
    // work with b
}

これは慣用的な囲碁です。がっかりすることはなく、意図に反することもありません。文字列をバイトごとに単純に反復処理しますが、これはまさにあなたがやりたいことです。

于 2013-01-17T12:57:56.373 に答える