@ledsun blog

無味の味は佳境に入らざればすなわち知れず

rustでgrep-lite 2

行番号を出力する機能が増えました。

fn main() {
    let search_term = "picture";
    let quote = "\
Every face, every shop, bedroom window, public-house, and
dark square is a picture feverishly turned--in search of what?
It is the same with books.
What do we seek through millions of pages?";
    let mut line_num: usize = 1;

    for line in quote.lines() {
        if line.contains(search_term) {
            println!("{line_num}: {line}");
        }
        line_num += 1;
    }
}

line_num++;はないようです。 まあ、なくても困りません。

fn main() {
    let search_term = "picture";
    let quote = "\
Every face, every shop, bedroom window, public-house, and
dark square is a picture feverishly turned--in search of what?
It is the same with books.
What do we seek through millions of pages?";
    for (i, line) in quote.lines().enumerate() {
        if line.contains(search_term) {
            let line_num = i + 1;
            println!("{line_num}: {line}");
        }
    }
}

enumerateというメソッドを使うとインデックスが帰ってくるようです。 JavaScriptArray.prototype.forEachみたいに同じ関数で、コールバック関数の引数がかわるわけではないんですね。 あ、forEachはイテレーターではないですね。 イテレーターとして比較するなら

  • Array.prototype.values()
  • Array.prototype.entries()

の方でした。 メソッドがわかれているのではなく、メソッドチェーンになっているのは興味深いです。 このループは2回回らないのでしょうか? 気にならないくらい速いのか? コンパイラがインライン化してしまうのか? 並列に実行されるのか? 興味深いです。

2つの値が返ってくる場合はline(i, line)のようにカッコでくくる必要があります。 パーサーの都合でしょうか?desutructuring assignmentみたいな文法があるのでしょうか?