for c in "नमस्ते".chars() { println!("{}", c); }
これだと文字列の長さ分の配列的なメモリ領域が確保されるそうなのので、あまり望ましくない(ヒープの乱れは心の乱れ)。Go だと
package main import "fmt" func main() { for _, c := range "नमस्ते" { fmt.Printf("%c\n", c) } }
で、各コードポイント単位で列挙できるんだが、同様なのはないものか。
標準ライブラリのドキュメントをつらつら見ていたら、ちょうどよいのがあった。
fn main(){ let word = "日本語テキスト"; for (size,code) in word.char_indices() { println!("{},{}",size,code) } }
0,日 3,本 6,語 9,テ 12,キ 15,ス 18,ト
実は最初、CharGPT 3.5 に本件を聞いていたんだが、chars()
は教えてくれても、char_indices()
の存在は教えてくれなかった。思うに、
- リファレンスに載ってるサンプルコードがただのテストコードで、for を使った実用的なコードになっていない
- 日本語のブログ記事で、このような内容を取り扱っているものがたまたまなかった
ったところだろうな。それで、学習データの中に入っていなかったと。
あと、.char_indices()
はループ以外の場所でも、
let mut char_indices = word.char_indices(); // イテレータのインスタンスを作成 assert_eq!(Some((0, 'g')), char_indices.next());
という形で使えて、勝手が良さそうだ。Go だと import "unicode/utf8"
した上で、utf8.DecodeRuneInString という別の関数を呼び出す形になる。