Go言語に入門してうろうろしてますが、ちょっと困った挙動があったので書いてみます。
症状
main.go
func main() {
l := strings.Split("", ",")
fmt.Printf("%#v\n", l) // []string{""}
fmt.Println(len(l)) // 1
}
見ての通り、空文字に対してsplitすると1要素の配列が返ってきており、そのため、この返り値をfor ~ range
などで回すとループの中の処理が実行されてしまいます。
ググってみたところ、区切り文字の数 + 1個の要素を返す仕様とのこと。
https://groups.google.com/d/msg/golang-nuts/S7U1iRmuydg/qKu3Wcl4oOcJ
fmt.Println(len(strings.Split(",,", ","))) // 3
fmt.Println(len(strings.Split(",", ","))) // 2
fmt.Println(len(strings.Split("", ","))) // 1
つまりこういう理屈ですか。う、うーん……$x^0 = 1$みたいなもので、わからないではないけれど、rubyに慣れていると戸惑いますね。
対処法
splitした結果に対してfor ~ range
の書き方をする場合などは空文字が来ることを考慮して、先にはじくか、ループの先頭で空文字判定してcontinue
するかの処理が必要そうです。
他言語(追記)
ふと思いついたので他の言語も試してみました。
言語 | 件数 |
---|---|
ruby | 0 |
Go | 1 |
JavaScript | 1 |
Python | 1 |
Perl | 0 |
PHP | 1 |
Java | 1 |
awk 1 | 1 |
vim script2 | 0 or 1 (keepempty次第) |
あっ、これ0の方が少数派だ。