Language
string: range のindexはrune番号ではなくバイト位置になる
文字列をrangeするとruneを取り出せますが、indexはUTF-8のバイトオフセットです。
Sourcerange.go
Go 1.22
package stringexample
func RuneByteIndexes(value string) []int {
indexes := make([]int, 0, len(value))
for index := range value {
indexes = append(indexes, index)
}
return indexes
}Testrange_test.go
Go 1.22
package stringexample
import (
"reflect"
"testing"
)
func Test文字列に対するrangeのindexはrune番号ではなくバイト位置になる(t *testing.T) {
if got, want := RuneByteIndexes("A🐹B"), []int{0, 1, 5}; !reflect.DeepEqual(got, want) {
t.Fatalf("RuneByteIndexes() = %v, want %v", got, want)
}
}01Assertion
このテストで確認できること
- A🐹Bをrangeしたindexは0, 1, 5になる
- 絵文字の次のBはrune番号2ではなくバイト位置5から始まる
rangeのindexで文字を切り出す場合は、バイト境界を扱っていることを意識します。文字単位の位置が必要なら[]runeへ変換する設計を検討します。
OBSERVED RESULT
input: "A🐹B"
indexes: [0 1 5]