Testing

https://doc.rust-lang.org/book/testing.html

テストの実施環境について。言語に標準でテストの仕組みが含んでいたり、ドキュメントに記載されている。これだけでも今どきの言語だという感じがします。

テストの実施方法はドキュメントを読んだ限りではシンプル。assert_eq!以外にもテスト用のマクロがあると思うので、実用となると色々と大変になるのでしょうが。

Raw Pointers

https://doc.rust-lang.org/book/raw-pointers.html

単に*で宣言したポインタは安全ではない(何も指し示していないかもしれない)ので、unsafe内で展開して使用する。

fn main() {
    let x = 5;
    let raw = &x as *const i32;
    // println!("raw points at {}", *raw);
    let points_at = unsafe { *raw };
    println!("raw points at {}", points_at);

    let mut y = 10;
    let raw_mut = &mut y as *mut i32;
    // println!("raw points at {}", *raw_mut);
    let points_at = unsafe { *raw_mut };
    println!("raw points at {}", points_at);

    // Explicit cast:
    let i: u32 = 1;
    let p_imm: *const u32 = &i as *const u32;

    // Implicit coercion:
    let mut m: u32 = 2;
    let p_mut: *mut u32 = &mut m;

    unsafe {
        let ref_imm: &u32 = &*p_imm;
        let ref_mut: &mut u32 = &mut *p_mut;
    }
}

Macros #2

https://doc.rust-lang.org/book/macros.html

再帰的にマクロを使ったり、マクロは奥が深そう。 章の量も他の章と比べ、明らかに多い。

unreachable!が面白い。デバッグ等で活躍しそう。

if false {
    unreachable!();
}

Macros

https://doc.rust-lang.org/book/macros.html

マクロ。

/* vec!と同じ働きをするマクロ定義 */
macro_rules! myvec {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

macro_rules! o_O {
    (
        $(
            $x:expr; [ $( $y:expr ),* ]
        );*
    ) => {
        &[ $($( $x + $y ),*),* ]
    }
}

macro_rules! foo {
    ($v:ident) => (let $v = 3;);
    () => ( fn b() { println!("b"); } );
}

fn main() {
    let x: Vec<u32> = myvec![1, 2, 3];
    println!("{:?}", x);

    let a: &[i32]
        = o_O!(10; [1, 2, 3];
                20; [4, 5, 6]);
    assert_eq!(a, [11, 12, 13, 24, 25, 26]);

    foo!(x);
    println!("{}", x);
    foo!();
    b();
}
$ cargo run
[1, 2, 3]
3
b

`Deref` coercions

https://doc.rust-lang.org/book/deref-coercions.html

*も型に合わせて定義できる。

use std::ops::Deref;

struct DerefExample<T> {
    value: T,
}

impl<T> Deref for DerefExample<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &self.value
    }
}

fn main() {
    let x = DerefExample { value: 'a' };
    assert_eq!('a', *x);
}