Associated Types

https://doc.rust-lang.org/book/associated-types.html

trait Graph {
    type N;
    type E;

    fn has_edge(&self, &Self::N, &Self::N) -> bool;
    fn edges(&self, &Self::N) -> Vec<Self::E>;
}

struct Node;
struct Edge;
struct MyGraph;

impl Graph for MyGraph {
    type N = Node;
    type E = Edge;

    fn has_edge(&self, n1: &Node, n2: &Node) -> bool {
        true
    }

    fn edges(&self, n: &Node) -> Vec<Edge> {
        Vec::new()
    }
}

fn main() {
    let graph = MyGraph;
    let obj = Box::new(graph) as Box<Graph<N=Node, E=Edge>>;
}

Casting Between Types

https://doc.rust-lang.org/book/casting-between-types.html

型のキャストについて。asを使用する。

use std::mem;

fn main() {
    let one = true as u8;
    let at_sign = 64 as char;
    let two_hundred = -56i8 as u8;
    println!("{}, {}, {}", one, at_sign, two_hundred);

    let a = 300 as *const char; // `a` is a pointer to location 300.
    let b = a as u32;
    println!("{}", b);

    unsafe {
        let a = [0u8, 1u8, 0u8, 0u8];
        let b = mem::transmute::<[u8; 4], u32>(a);
        println!("{}", b); // 256
        // Or, more concisely:
        let c: u32 = mem::transmute(a);
        println!("{}", c); // 256
    }
}
$ cargo run
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/4_29_casting_between_types`
1, @, 200
300
256
256

Type Aliases

https://doc.rust-lang.org/book/type-aliases.html

typeキーワードで型に別名をつけられる。C言語でいうtypedef

fn main() {
    type Name = String;
    let x: Name = "Hello".to_string();
    println!("{}", x);

    type Num = i32;
    let x: i32 = 5;
    let y: Num = 5;
    if x == y {
       println!("x == y");
    }
}
$ cargo run
   Compiling 4_28_type_aliases v0.1.0 (file:///Users/miura/work/git-work/exercises/The_Rust_Programming_Language/4_28_type_aliases)
    Finished debug [unoptimized + debuginfo] target(s) in 0.34 secs
     Running `target/debug/4_28_type_aliases`
Hello
x == y

Attributes

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

#[hoge]という記法をattributeというものらしい。

#[cfg(target_os = "macos")]  // macosだけで動作する
fn only() {
    println!("mac");
}

#[cfg(target_os = "linux")] // linuxだけで動作する
fn only() {
    println!("linux");
}

#[test] // cargo testで動作する
fn hoge() {
    only();
}

fn main() {
    println!("Hello, world!");
    only();
}
$ cargo test
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running target/debug/4_27_attributes-d9c4b09d37979797

running 1 test
test hoge ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured

$ cargo run
   Compiling 4_27_attributes v0.1.0 (file:///Users/miura/work/git-work/exercises/The_Rust_Programming_Language/4_27_attributes)
    Finished debug [unoptimized + debuginfo] target(s) in 0.31 secs
     Running `target/debug/4_27_attributes`
Hello, world!
mac

const and static

https://doc.rust-lang.org/book/const-and-static.html

定数を定義する方法。letでもmutつけなければ定数代わりになると思ったが、メモリ配置のされ方が違ったりするらしい。 また、同じスコープ内で同じ名前の定義を行う場合、letの場合は可能だったが、conststaticではできなかった。

const N: i32 = 4;
static M: i32 = 4;
static mut L: i32 = 4;

fn main() {
    const N: i32 = 5;
    // const N: i32 = 6; // error
    static M: i32 = 5;
    // static M: i32 = 6; // error
    static mut L: i32 = 5;
    // static mut L: i32 = 6; // error
    unsafe {
        L += 1;
        println!("{}, {}, {}", N, M, L);
    }
}
$ cargo run
    Finished debug [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/4_26_const_and_static`
5, 5, 6

Crates and Modules

https://doc.rust-lang.org/book/crates-and-modules.html

Rustはデフォルトがプライベートで、pubをつけるとグローバルになる。

extern crate phrases as sayings;

use sayings::japanese::greetings as ja_greetings;
use sayings::japanese::farewells::*;
use sayings::english::{self, greetings as en_greetings, farewells as en_farewells};

fn main() {
    println!("Hello in English; {}", en_greetings::hello());
    println!("And in Japanese: {}", ja_greetings::hello());
    println!("Goodbye in English: {}", english::farewells::goodbye());
    println!("Again: {}", en_farewells::goodbye());
    println!("And in Japanese: {}", goodbye());
}

でエラーが出たのだけど、原因は、mod farewellspubをつけていないせいだった。

pub use self::greetings::hello;
pub use self::farewells::goodbye;

pub mod farewells;
pub mod greetings;