暇人じゃない

Rust 入門日記 (2) 型〜マクロ
Rust

実践 Rust プログラミング入門 を読んで気になったところをメモするシリーズ。

Result, Option

  • Option: データが存在する場合、存在しない場合を表現する列挙型
  • Result: 処理の結果が成功かエラーかを表現する列挙型

Result のハンドリング

Box

  • Rust の値は多くの場合、メモリのスタック領域に確保される

    • 高速に扱うことが出来るが、コンパイル時にサイズが分かっており、固定サイズでなくてはいけない
  • Box を使うと値はヒープ領域に確保される
  • 確保したいタイミングで必要な文を確保する
  • ヒープ領域に任意の型を格納し、スタック領域にヒープ領域へのポインタを置く
fn main() {
    let byte_array = [b'h', b'e'];
    print(Box::new(byte_array))
}

fn print(s: Box<[u8]>) {
    println!("{:?}", s)
}

const と static

  • const: コンパイラがビルドをする時に実際の値に置き換えられる
  • static: グローバルスコープで定義した static の値はどこからでも変更ができてしまうため危険

    • 実行時に決まる定数を定義したい場合は lazy_static がおすすめ

match

fn main() {
  let i: i32 = 2;

  match i {
      1 => println!("1"),
      _ => println!("other"),
  }
}

Iterator

  • for ループはデータの集合から要素を取り出して繰り返し処理をすることができる

    • データの集合に Iterator トレイトが実装されているため
  • 自作した型に Iterator トレイトを適用する例
fn main() {
  let it = Iter {
      current: 0,
      max: 10,
  };
  for num in it {
      println!("{}", num);
  }
}

struct Iter {
    current: usize,
    max: usize,
}

impl Iterator for Iter {
    type Item = usize;

    fn next(&mut self) -> Option<usize> {
        self.current += 1;
        if self.current - 1 < self.max {
            Some(self.current - 1)
        } else {
            None
        }
    }
}

impl

  • 関数を構造体に紐づけておけば、オブジェクト指向のクラスのような扱いをすることができる
fn main() {
    let p = Person {
        name: String::from("Taro"),
        age: 20,
    };
    p.say_name().say_age();
}

struct Person {
    name: String,
    age: u32,
}

impl Person {
    fn say_name(&self) -> &Self {
        println!("I am {}.", self.name);
        self
    }
    fn say_age(&self) -> &Self {
        println!("I am {} year(s) old.", self.age);
        self
    }
}
fn main() {
    let p = Person::new("Taro", 20);
    p.say_name().say_age();
}

impl Person {
    fn new(name: &str, age: u32) -> Person {
        Person {
            name: String::from(name),
            age: age,
        }
    }
}

マクロ

実装補助用のマクロ

いずれも実装が行われていない部分があっても型検査を通す

  • unimplemented!: 未実装を示す
  • todo!: 今後実装を示す
  • unreachable: match で条件を網羅していることを判定できない

About

chocoby (GitHub / Twitter / Email)

個人事業主のソフトウェア開発者です。 Ruby と Rails を使った Web サービスの開発を得意としています。

CurryBu というサービスを作ったり、jp_prefecture という Gem を作っています。