目次

Rustの勉強[CLI作成編 その9]

(更新: )ぎじゅつ

はじめに

#

NO IMAGEThe Rust Programming Language 日本語版 - The Rust Programming Language 日本語版
を読んでいる

  • 今日社内の勉強会でこれを予習したがボコボコにされた
  • 頑張るぜ

お勉強

#

メモ

#

NO IMAGEテスト駆動開発でライブラリの機能を開発する - The Rust Programming Language 日本語版

  • こっからスタート

言い換えると、コンパイラにsearch関数に返されるデータは、 search関数にcontents引数で渡されているデータと同期間生きることを教えています。 これは重要なことです!スライスに参照されるデータは、参照が有効になるために有効である必要があるのです; コンパイラがcontentsではなくqueryの文字列スライスを生成すると想定してしまったら、 安全性チェックを間違って行うことになってしまいます。

  • Vec<String>にすれば記述の管理が楽になるって話を上司とした
    • たくさん利用しないならパフォーマンスに差があることはまれ
  • でもクソデカ文字列を処理したらそのままコピーされるし、呼び出し回数に比例して巨大になるので注意が必要
- error[E0106]: missing lifetime specifier
(エラー: ライフタイム指定子が欠けています)
 --> src/lib.rs:5:51
  |
5 | pub fn search(query: &str, contents: &str) -> Vec<&str> {
  |                                                   ^ expected lifetime
parameter
  |
  = help: this function's return type contains a borrowed value, but the
  signature does not say whether it is borrowed from `query` or `contents`
  (助言: この関数の戻り値は、借用された値を含んでいますが、シグニチャにはそれが、
  `query`か`contents`から借用されたものであるかが示されていません)
  • これこれ
  • 実装編
    • linesメソッドを作ろう

linesメソッドはイテレータを返します。

  • ほう、イテレーター
  • 実はちゃんとやったことがない
pub fn search<'a>(query: &str, contents: &'a str) -> Vec<&'a str> {
    let mut results = Vec::new();

    for line in contents.lines() {
        if line.contains(query) {
            results.push(line);
        }
    }

    results
}
  • これを書いた
  • containsメソッドがあるんだな
  • いけーーーーーcargo testだーー
running 1 test
test test::one_result ... FAILED

failures:

---- test::one_result stdout ----

thread 'test::one_result' (14055314) panicked at src/lib.rs:59:9:
assertion `left == right` failed
  left: ["safe, fast, productive."]
 right: ["                        safe, fast, productive."]
stack backtrace:
   0: __rustc::rust_begin_unwind
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/std/src/panicking.rs:698:5
   1: core::panicking::panic_fmt
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/panicking.rs:80:14
   2: core::panicking::assert_failed_inner
   3: core::panicking::assert_failed
             at /nix/store/1mnwkvhnnkbsbphhaiq1pw6gi8qm25gk-rust-default-1.92.0/lib/rustlib/src/rust/library/core/src/panicking.rs:399:5
   4: minigrep::test::one_result
             at ./src/lib.rs:59:9
   5: minigrep::test::one_result::{{closure}}
             at ./src/lib.rs:50:20
   6: core::ops::function::FnOnce::call_once
             at /nix/store/1mnwkvhnnkbsbphhaiq1pw6gi8qm25gk-rust-default-1.92.0/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
   7: core::ops::function::FnOnce::call_once
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.


failures:
    test::one_result

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
  • 怒られた

テストが通り、動いていることがわかりました!

  • 通らねーよばかやろーーーーー

  • 調査しよう

  • なんかpanicしているな

left: ["safe, fast, productive."]
right: ["                        safe, fast, productive."]
  • なんかめっちゃ変な空白が入っているな
  • わかったわ
#[cfg(test)]
mod test {
    use super::*;

    #[test]
    fn one_result() {
        let query = "duct";
        // RUstは
        // 安全で速く生産性も高い。
        // 3つ選んで。
        let contents = "\
                        Rust:
                        safe, fast, productive.
                        Pick three,";
        assert_eq!(vec!["safe, fast, productive."], search(query, contents))
    }
}
  • これ一見よさそうに見えるが
#[test]
    fn one_result() {
        let query = "duct";
        // RUstは
        // 安全で速く生産性も高い。
        // 3つ選んで。
        let contents = "\
Rust:
safe, fast, productive.
Pick three,";
        assert_eq!(vec!["safe, fast, productive."], search(query, contents))
    }
}
  • 文字列のインデントをこうする必要があった
running 1 test
test test::one_result ... ok

test result: ok. 1 passed
0 failed
0 ignored
0 measured
0 filtered out
finished in 0.00s
  • 予想どおりOKになった

まとめ

#
  • 勝手にRustはほとんどの処理を書く必要があると思ったがちゃんとlineとかcontainsがあった

    • 当たり前だけどなんかうれしい
  • デバッグもこうやって理解しながらやるのはおもしろい

  • プログラミング楽しいじゃん

  • 次はrun関数に実装!

NO IMAGEテスト駆動開発でライブラリの機能を開発する - The Rust Programming Language 日本語版