kdnakt blog

hello there.

Rust dojo第26回を開催した

2週間ぶりの第26回です。

前回はこちら。

kdnakt.hatenablog.com

 

 

[第26回の様子]

2022/01/26に第26回を開催した。

 

1/19に元々開催予定だったが、自分が急な発熱でダウンした結果(コロナは陰性)その日はRust雑談の会(回?)が開催された。社内でのRustの使い所とか、参考書籍の紹介があったらしい。実践Rust入門とかプログラミングRust 第2版とか。

 

第26回の内容としてはRust By Example 日本語版の「9.2.2. 捕捉時の型推論」に取り組んだ。

 

参加者は9人。参加者が増えて嬉しい😊

 

[学んだこと]

fn apply<F>(f: F) where
    F: Fn() {
    f();
}

fn main() {
    let greeting = "hello";
    let diary = || {
        println!("I said {}.", greeting);
    };
    apply(diary);
}
  • クロージャが可変参照を捕捉する場合にはFnMut()型になる
// mut修飾子が必要
fn apply<F>(mut f: F) where
    F: FnMut() {
    f();
}

fn main() {
    let mut farewell = "goodbye".to_string();
    let diary = || {
        // farewellの値を変更している
        farewell.push_str("!!!");
        println!("Then I screamed {}.", farewell);
    };
    apply(diary);
}
fn apply<F>(f: F) where
    F: FnOnce() {
    f();
}

fn main() {
    use std::mem;
    // to_owned()はコピーでなく移動が起きる型を作る
    let farewell = "goodbye".to_owned();
    let diary = || {
        println!("Then I screamed {}.", farewell);
        mem::drop(farewell);
    };
    apply(diary);
    
    // ↑で移動しているので2回目に呼び出すとコンパイルエラー:error[E0382]: use of moved value: `diary`
    // apply(diary);
}
  • ちなみに、whereでトレイトを指定しているが、関数名の後の<>のところで指定しても同じ意味になる
fn apply_to_3_v1<F>(f: F) -> i32 where
    // Fは引数がi32で戻り値がi32の関数
    F: Fn(i32) -> i32 {
    f(3)
}

// 先に型を指定することもできるが全体像が掴みづらくなるかも...
fn apply_to_3_v2<F: Fn(i32)->i32>(f: F) -> i32 {
    f(3)
}

fn main() {
    let double = |x| 2 * x;
    println!("3 doubled: {}", apply_to_3_v1(double));
    println!("3 doubled: {}", apply_to_3_v2(double));
}
  • このあたりのことはテキストのもう少し先で詳しく出てきそう

doc.rust-jp.rs

 

[まとめ]

モブプログラミングスタイルでRust dojoを開催した。

参照とか値の話が出てくるたびに、Rustのコンパイラは賢いなあ...と思う。

 

今週のプルリクエストはこちら。

github.com