Rust dojo第50回を開催した

第50回です。前回はこちら。

kdnakt.hatenablog.com

 

 

[第50回の様子]

2022/08/10に第50回を開催した。

 

内容としてはRust By Example 日本語版の16. トレイトの続きで、「16.3. 演算子オーバーロード」、「16.4. メモリ解放」、「16.5. イテレータ」に取り組んだ。

 

参加者は自分を入れて3人。みんな夏季休暇かしら...。

 

[学んだこと]

use std::ops;

struct Foo;
struct Bar;

#[derive(Debug)]
struct FooBar;

// Foo + BarはFoo.add(Bar)に変換される
impl ops::Add<Bar> for Foo {
  type Output = FooBar;
  
  fn add(self, _rhs: Bar) -> FooBar {
    println!("> Foo.add(Bar) was called");
    FooBar
  }
}

fn main() { 
  println!("Foo + Bar = {:?}", Foo + Bar);
  // > Foo.add(Bar) was called 
  // Foo + Bar = FooBar
}

kdnakt.hatenablog.com

kdnakt.hatenablog.com

  • std::mem::drop()関数をdrop()で直接呼び出せる、という点がこの節で新しくわかった
  • 16.5. イテレータ
  • Iteratorトレイトは次の要素を取得するnext()メソッドを実装する
  • next()の戻り値はOption型なので、SomeかNoneを返す
    • 次の要素がある場合はSomeでラップした値を返す
    • 次の要素がなくなったらNone
  • フィボナッチ数列を返すFibonacci構造体にIteratorを実装すると次のようになる
struct Fibonacci {
    curr: u32,
    next: u32,
}

impl Iterator for Fibonacci {
    // 要素の型はu32
    type Item = u32;
    
    fn next(&mut self) -> Option {
        let new_next = self.curr + self.next;

        self.curr = self.next;
        self.next = new_next;

        // フィボナッチ数列には終わり常にSome
        Some(self.curr)
    }
}

// フィボナッチ数列のジェネレータを返す。
fn fibonacci() -> Fibonacci {
    Fibonacci { curr: 0, next: 1 }
}

fn main() {
    println!("The first four terms of the Fibonacci sequence are: ");
    for i in fibonacci().take(4) {
        println!("> {}", i);
    }
    // The first four terms of the Fibonacci sequence are: 
    // > 1
    // > 1
    // > 2
    // > 3
}
  • イテレータはSomeでラップされた値を返すのであれば> 1ではなく> Some(1)となるのでは?と思っていたら、forイテレータの結果をアンラップして変数に束縛するらしい。なるほど。
  • 次のように直接next()を呼び出すとSomeでラップされたままの値が取れる
fn main() {
    let mut sequence = 0..3; // 0, 1, 2を返す

    println!("Four consecutive `next` calls on 0..3");
    println!("> {:?}", sequence.next()); // > Some(0)
    println!("> {:?}", sequence.next()); // > Some(1)
    println!("> {:?}", sequence.next()); // > Some(2)
    println!("> {:?}", sequence.next()); // > None
}
  • 配列やスライスは直接for文で扱えないので、iter()メソッドでイテレータに変換して扱う
fn main() {
    let array = [1u32, 3, 3, 7];

    println!("Iterate the following array {:?}", &array);
    for i in array.iter() {
        println!("> {}", i);
    }
    // Iterate the following array [1, 3, 3, 7]
    // > 1
    // > 3
    // > 3
    // > 7
}

 

[まとめ]

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

今日は比較的簡単だった気がする。

 

プルリクエストはそのうち追記予定。