標準愚痴出力

個人的なIT作業ログです。もしかしたら一般的に参考になることが書いているかもしれません(弱気

勉強メモ:Rust で日本語を一文字ずつ列挙する

for c in "नमस्ते".chars() {
    println!("{}", c);
}

これだと文字列の長さ分の配列的なメモリ領域が確保されるそうなのので、あまり望ましくない(ヒープの乱れは心の乱れ)。Go だと

package main

import "fmt"

func main() {
    for _, c := range "नमस्ते" {
        fmt.Printf("%c\n", c)
    }
}

で、各コードポイント単位で列挙できるんだが、同様なのはないものか。

標準ライブラリのドキュメントをつらつら見ていたら、ちょうどよいのがあった。

str - Rust

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 という別の関数を呼び出す形になる。