Introduction - Rust By Example 日本語版 を見ながら Rust の基本文法をおさらいする
mut
キーワードを用いるlet x = 1; // x = 2; => Error let mut y = 1; let y = 2; let z; z = 123;
io::stdin.read_line
は引数に mut &String
をとるlet mut input = String::new(); io::stdin().read_line(&mut input).expect("Error"); println!("Input value: {}", input);
fn
キーワードで定義できる
pub fn add(a: u64, b: u64) -> u64 { a + b } #[cfg(test)] mod tests { use super::*; #[test] fn test_add() { let value = add(1, 2); assert_eq!(value, 3); } }
let xs: [i32; 2] = [1, 2]; println!("{}", xs.len()); //=> 2 let a = (1, 2); let b: i32 = a.0 + a.1; let c: i32 = b.pow(2);
struct
と 列挙型 enum
として定義できるconst
あるいは static
というキーワードで定義できる// Unit struct Nil; let _nil = Nil; // Named Tuple struct Pair(i32, i32); let pair = Pair(1, 2); // Classical Struct struct Point { x: f32, y: f32, } let p = Point { x: 0.1, y: 0.2 }; // Enum enum Event<T> { Next(T), Error, Complete, } impl<T> Event<T> { fn echo(&self) { match self { // Self は Event の type alias Self::Next(_) => println!("Next"), Self::Error => println!("Error"), Self::Complete => println!("Complete"), } } }
trait
という言語機能もあるstruct Adder { a: u32, b: u32, } impl Adder { fn new(a: u32, b: u32) -> Self { Adder { a, b } } fn calc(&self) -> u32 { (*self).a + (*self).b } } fn main() { let x = Adder::new(1, 3); println!("1 + 3 = {:?}", x.calc()); //=> 4 }
self
には次の 3 つの種類がある
&self
: インスタンスメソッド&mut self
: 該当のオブジェクトがミュータブルである必要のあるインスタンスメソッドself
: オブジェクトのリソースを消費するインスタンスメソッドstruct Counter { value: u32, } impl Counter { fn new() -> Self { Counter { value: 0 } } fn add(&mut self) { self.value += 1; } fn peek(&self) -> u32 { self.value } fn destory(self) { // do nothing } } fn main() { let immutable_counter = Counter::new(); println!("count: {:?}", immutable_counter.peek()); // immutable_counter.add(); => ERROR // ミューテーションを起こすメソッドをコールするためには変数を let mut で宣言する必要がある // ただしオブジェクトの所有権を受け渡すような操作は受け付ける immutable_counter.destory(); // println!("count: {:?}", counter.peek()); => moved out したあとのオブジェクトは操作できない let mut counter = Counter::new(); println!("count: {:?}", counter.peek()); counter.add(); println!("count: {:?}", counter.peek()); counter.add(); println!("count: {:?}", counter.peek()); counter.add(); println!("count: {:?}", counter.peek()); counter.destory(); //=> `counter` moved due to this method call println!("count: {:?}", counter.peek()); //=> Error: this function takes ownership of the receiver `self`, which moves `counter` }
Box<T>
を作成することにより値をヒープに割り当てられる
T
の値への単なるスマートポインタ*
によりデリファレンスできるfn main() { let boxed_number: Box<u128> = Box::new(1); let number: u128 = *boxed_number; println!("size: {:?}", mem::size_of_val(&boxed_number)); //=> size: 8(ポインタのサイズ) println!("size: {:?}", mem::size_of_val(&number)); //=> size: 16(128 bit = 8 bit * 16) }
fn main() { let x = 123; { let x = 234; println!("{:?}", x); //=> 234 } println!("{:?}", x); //=> 123 }
i
, u
, f
などを置いて型を指定できるlet a = 12i8; let b = 1234i16; let c = 1234i32; let d = 1234i64; let e = 1234u128; let f = 1234f32;
let f = |x| x + 1; let res = f(1); println!("{}", res); //=> 2
つづきはここから(作業メモ) https://doc.rust-jp.rs/rust-by-example-ja/conversion.html
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです