基本操作
変数の設定
1 |
let x = 1; |
定数の設定
1 2 3 4 |
const PI: f32 = 3.141; fn main() { println!("円周率:{}", PI); } |
・定数はコード全体で何度も使われる値を設定できる
・型設定が必須
・大文字のスネークケース SCREAMING_SNAKE_CASEを使用する
配列
1 2 3 4 5 6 7 |
fn main(){ let nums: [i32; 5] = [1,2,3,4,5]; //配列の表示 println!("{:?}", nums); //先頭の要素を取得 println!("{}", nums[0]); } |
・全要素が同じ型の要素の集まり(固定長)
・データ型:” [T;N] “ →Tは要素の方、Nはコンパイル時に決まる固定長(配列の要素数)
・
関数
1 2 3 4 5 6 7 8 9 |
//関数の作成時に引数の型、戻り値の型を指定 fn sub(x: i32, y: i32) -> i32{ return x-y; } fn main(){ let ans = sub(100,50); println!("{}", ans) } |
・関数名は小文字のスネークケース
・関数作成時に引数の型、戻り値の方を指定する
関数:複数の戻り値
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
//複数の戻り値はタプルで指定 fn add(x: i32, y: i32) -> (i32,i32) { return (y+100,x+1000); } fn main(){ //戻り値をタプルのまま取得 let result = add(50,500); //タプルの各要素を表示 println!("{} {}", result.0, result.1); //戻り値をタプルから取り出して取得 let (i,j) = add(result.0, result.1); println!("{} {}", i,j); } |
・複数の戻り値を使用するときはタプルを指定
・タプルのまま取得することも、各要素を取得することも可能
関数:空の戻り値
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//戻り値に空のタプルを自身で指定 fn no_return_function() -> () { return (); } //戻り値に型を指定しない→unitが返される fn no_return_function2() { } fn main() { let a = no_return_function(); let b = no_return_function2(); println!("a → {:?}", a); println!("b → {:?}", b); } |
・戻り値の型が指定されていない場合、unitと呼ばれる空のタプルを返す
制御構文
if文
1 2 3 4 5 6 7 8 9 10 11 12 |
fn main() { let x = 20; if x < 50 { println!("50より小さい"); } else if x == 20 { println!("20と等しい"); } else { println!("50以上"); } } |
・Pythonに近い感覚
無限ループ:loop
1 2 3 4 5 6 7 8 9 |
fn main() { let mut x = 0; loop { x += 1; if x == 50 {break;} } println!("{}", x); } |
・無限ループ処理を行いたいときはloopを使う。
・終了したいときはbreak
・mutはミュータブルな変数としたいときに記載。これにより後から変数の値を変更できる
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fn main() { let mut x = 0; let v = loop { x += 1; if x == 13 { break "13を発見"; } }; println!("loopの戻り値:{}", v) } |
・loopはbreakで抜けた時に戻り値を設定することができる
無限ループ:while
1 2 3 4 5 6 7 8 9 10 |
fn main() { let mut x = 5; //50以外なら1を加える無限ループ。xが50ならループ終了 while x != 50 { x += 1; } println!("{}", x) } |
・whileでも無限ループができる。
・while文での条件に一致しなかった時に自動的に終了
for文
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fn main() { //0から4までの5回ループ for i in 0..5 { println!("{}", i); } //0から5までの6回ループ for j in 0..=5 { println!("{}", j); } } |
・Rustのfor文では終了番号を含めるか含めないかを自分で選ぶことができる
・含めない場合は ” .. ”
・含める場合は ” ..= ”
match
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
fn main() { let x = 42; match x { 0 => { println!("0"); } 1 | 2 => { println!("1か2"); } 3..=9 => { println!("3~9"); } matched_num @ 10..=100 => { println!("{} 10~100", matched_num); } //どれにもマッチしない場合は必ず _ とする? _ => { println!("not found"); } } } |
・マッチした条件に応じて処理を変える
・条件は網羅的に書かなければならない
ブロック式から値を返す
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
fn example() -> i32 { let x = 42; // Rust の三項式 let v = if x < 42 { -1 } else { 1 }; println!("if より: {}", v); let food = "ハンバーガー"; let result = match food { "ホットドッグ" => "ホットドッグです", // 単一の式で値を返す場合、中括弧は省略可能 _ => "ホットドッグではありません", }; println!("食品の識別: {}", result); let v = { // ブロックのスコープは関数のスコープから分離されている let a = 1; let b = 2; a + b }; println!("ブロックより: {}", v); // Rust で関数の最後から値を返す慣用的な方法 v + 4 } fn main() { println!("関数より: {}", example()); } |
※ここは復習
演算子
ジェネリック型
Result
概要
・Resultと呼ばれるジェネリックな列挙型が組み込まれている。
・失敗する可能性のある値を返すことができる
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
//[1] fn do_something_that_might_fail(i:i32) -> Result<f32,String> { if i == 42 { Ok(13.0) } else { Err(String::from("正しい値ではありません")) } } fn main() { let result = do_something_that_might_fail(42); match result { Ok(v) => println!("発見 {} ", v), Err(e) => println!("Error: {} ", e), } } |
・42なら13.0を返し、42以外の数値なら正しくないことを文字で返す関数
・[1]Result<f32,Stirng>で内部の条件分岐に応じて返す値の型を指定
mainでもResultを使える
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
fn do_something_that_might_fail(i: i32) -> Result<f32, String> { if i == 100 { Ok(10.0) } else { Err(String::from("正しい値ではありません")) } } fn main() -> Result<(), String> { let result = do_something_that_might_fail(10); match result { Ok(v) => println!("正しい値です。{}",v), Err(_e) => { return Err(String::from("mainで何か問題が起きました。")); } } Ok(()) } |
・Resultはmain関数で使用してエラーが発生した時に返すことができる。
→エラー処理に使える
簡潔に書くことができる
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fn do_something_that_might_fail(i: i32) -> Result<f32, String> { if i == 100 { Ok(1.0) } else { Err(String::from("正しい値ではありません")) } } fn main() -> Result<(), String> { let v = do_something_that_might_fail(100)?; println!("発見 {}", v); Ok(()) } |
・main関数内部でdo_something_that_might_fale関数を呼び出す際、行末の;の前に?を付けることで簡潔に書くことができる
エラー
error[E0425]: cannot find value Pi in this scope
・変数Piが定義されていない
・変数名の書き間違いなど
error[E0308]: mismatched types
・型が合わない
・配列設定時の要素数と実際の要素数があっていないなど
error[E0277]: fn() {no_return_function} doesn’t implement Debug
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//戻り値に空のタプルを自身で指定 fn no_return_function() -> () { return (); } //戻り値に型を指定しない→unitが返される fn no_return_function2() { } fn main() { // () がない let a = no_return_function; let b = no_return_function2(); println!("a → {:?}", a); println!("b → {:?}", b); } |
・関数呼び出し時に” () “が抜けているなど
その他
スネークケース:SCREAMING_SNALE_CASE
・変数の命名規則
・単語と単語の間にアンダースコアを置く ” _ ”
・各単語の頭文字は小文字
キャメルケース
・変数の命名規則
・変数名の最初の単語は小文字、それ以降は大文字にする
・例:iPhone、eBayなど
コメント