Unsized Types
https://doc.rust-lang.org/book/unsized-types.html
サイズ不定の型を定義できるみたい。Rustは型の扱いが厳格だと思っていたので驚き。
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
の場合は可能だったが、const
、static
ではできなかった。
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 farewells
にpub
をつけていないせいだった。
pub use self::greetings::hello; pub use self::farewells::goodbye; pub mod farewells; pub mod greetings;