Closed9
省メモリでstringを反転(Go)

前提
- ヒープに置かれたstring型の文字列がある
- 文字は全て1byte文字なので、runeにする必要はない
- できるだけ(曖昧)省メモリにする

お察しのように競プロあるいはアルゴリズムの文脈

もし[]byteだったら
何も難しいことはなく、こんな感じでおしまい

b := []byte("abc")
for i := 0; i < len(b)/2; i++ {
b[i], b[len(b)-1-i] = b[len(b)-1-i], b[i]
}

これがstring
で渡されてくると、string
はイミュータブルなので困ってしまう。
ということでunsafe
を使った黒魔術が必要な見込み。

検索すると安定のmattnさんブログ

以下のような関数で、string
の先頭アドレスとその長さを持った[]byte
が作れるので、そいつに先ほどのような反転処理をかませばよい。(もちろんマルチバイト文字が無い前提でしか使えない)
func StringToBytes(s string) []byte {
return unsafe.Slice(unsafe.StringData(s), len(s))
}

作った[]byte
を操作すれば元のstring
をいじれる。元のstring
がスタックに置かれているとパニックする。そりゃそうですよねぇ…。さすがunsafe
だぜ!(変なテンション)

結論:前工程と良く相談して「本当にstring
で渡さないかんの!?[]byte
じゃいかんの!?」と問い詰めましょう。
このスクラップは2023/09/30にクローズされました