💨
Goの標準のutf8.RuneStart関数がエレガントすぎる
先日以下の記事を書きました。
ここでUTF-8の最初の文字かどうかの判定を以下の自作した関数で実装していました。
const (
t1 = 0b00000000
tx = 0b10000000
t2 = 0b00000110
t3 = 0b00001110
t4 = 0b00011110
)
func isUTF8LeadByte(tmp byte) bool {
if tmp&tx == t1 {
return true
}
tmp >>= 3
if tmp == t4 {
return true
}
tmp >>= 1
if tmp == t3 {
return true
}
tmp >>= 1
if tmp == t2 {
return true
}
return false
}
と思ったらなんと、標準パッケージに全く同趣旨のutf8.RuneStart
関数が存在していました。しかも実装はたったの1行でした。
func RuneStart(b byte) bool { return b&0xC0 != 0x80 }
何でこうなるのか、ぱっと見では分からなかったのですが、以下の本より図を引用します。
[改訂新版]プログラマのための文字コード技術入門:書籍案内|技術評論社の153pより
これを眺めると、00か01始まりならASCIIで、それ以外は11で始まることは明白です。つまり10でないことを確認するだけで十分です。
全く思いつかなかったですし、こんなエレガントな解決方法があることを知って驚きました。計測していませんが、速度も圧倒的に速いはずです。脱帽です。早速自作関数は捨てて、標準パッケージに書き換えます。
Discussion