🦞
Tour of Rust の個人的文法まとめ
はじめに
Tour of Rust 日本語版 をやってみて、Rustのコーディング規則や知らなかった知識などをまとめていきます。
基本的に自分が見返す用なので、網羅性についてはご容赦ください。
1章 - 基礎
変数
- 宣言時は
let
を使用 - 型推論可能
- 型指定可能 (データ型一覧)
// x の型を指定 let x: f64 = 3.14159; println!("{}", x);
- 変数名はスネークケース
変数の変更
- 可変(再代入可能)な変数には
mut
を使用
fn main() {
let mut x = 42;
println!("{}", x);
x = 13;
println!("{}", x);
}
// => 42
// => 13
基本的な型
- ブール型
-
true
,false
-
- 符号なし整数型
-
u8
,u32
,u64
,u128
-
- 符号あり整数型
-
i8
,i32
,i64
,i128
-
- ポインタサイズ整数型
-
usize
,isize
- メモリ内のインデックスとサイズを表す
-
- 浮動小数点型
-
f32
,f64
-
数値型は、数値の最後に型を付加することでも型指定可能
let a = 12u8;
let c = 4.3f32;
基本型の変換
- 数値型の型変換では型を明示する
-
as
を用いることで型変換可能
-
fn main() {
let a = 13u8;
let b = 7u32;
let c = a as u32 + b;
println!("{}", c);
let t = true;
println!("{}", t as u8);
}
// => 20
// => 1
定数
- 宣言時は
const
を使用 - 明示的な型指定が必要
- 定数名は大文字のスネークケース(SCREAMING_SNAKE_CASE)
const PI: f32 = 3.14159;
fn main() {
println!(
"ゼロからアップル {} を作るには、まず宇宙を創造する必要があります。",
PI
);
}
// => ゼロからアップル 3.14159 を作るには、まず宇宙を創造する必要があります。
配列
- データ型は [T; N]
- T : 要素の型
- N : コンパイル時に決定される固定長(要素数)
- array[x] で要素取得可能
- x は
usize
型のインデックスである
- x は
fn main() {
let nums: [i32; 3] = [1, 2, 3];
println!("{:?}", nums);
println!("{}", nums[1]);
}
// => [1, 2, 3]
// => 2
関数
- 戻り値の型は矢印の後に書く
- 戻り値は最後の式を暗黙的に返す(rubyと同じ)
- 関数名はスネークケース
fn add(x: i32, y: i32) -> i32 {
return x + y;
}
fn main() {
println!("{}", add(42, 13));
}
// => 55
複数の戻り値
- 戻り値をタプルで返すことで複数の値を返すことが可能
fn swap(x: i32, y: i32) -> (i32, i32) {
return (y, x);
}
fn main() {
// 戻り値をタプルで返す
let result = swap(123, 321);
println!("{} {}", result.0, result.1);
// タプルを2つの変数に分解
let (a, b) = swap(result.0, result.1);
println!("{} {}", a, b);
}
// => 321 123
// => 123 321
空の戻り値
- 戻り値の型が指定されていない場合、空のタプル(unit)を返す
2章 - 基本制御フロー
if/else if/else
- よくある条件分岐
fn main() {
let x = 42;
if x < 42 {
println!("42 より小さい");
} else if x == 42 {
println!("42 に等しい");
} else {
println!("42 より大きい");
}
}
// => 42に等しい
loop
- よくあるループ
fn main() {
let mut x = 0;
loop {
x += 1;
if x == 42 {
break;
}
}
println!("{}", x);
}
// => 42
- breakで値を返すことも可能
fn main() {
let mut x = 0;
let v = loop {
x += 1;
if x == 13 {
break "13 を発見";
}
};
println!("loop の戻り値: {}", v);
}
// => loop の戻り値: 13 を発見
while
- 条件付きのループ
fn main() {
let mut x = 0;
while x != 42 {
x += 1;
}
}
for
- イテレータとして評価式を反復
-
..
演算子は開始番号から終了番号の手前までの数値を生成する -
..=
演算子は開始番号から終了番号までの数値を生成する
fn main() {
for x in 0..5 {
println!("{}", x);
}
for x in 0..=5 {
println!("{}", x);
}
}
// => 0
// => 1
// => 2
// => 3
// => 4
// => 0
// => 1
// => 2
// => 3
// => 4
// => 5
match
- 値の取り得る全ての条件を評価し、真である場合のコードを実行する
- switch文と同等
fn main() {
let x = 42;
match x {
0 => {
println!("found zero");
}
// 複数の値にマッチ
1 | 2 => {
println!("found 1 or 2!");
}
// 範囲にマッチ
3..=9 => {
println!("found a number 3 to 9 inclusively");
}
// マッチした数字を変数に束縛(バインディング)
matched_num @ 10..=100 => {
println!("found {} number between 10 to 100!", matched_num);
}
// どのパターンにもマッチしない場合のデフォルトマッチが必須
_ => {
println!("found something else!");
}
}
}
// => found 42 number between 10 to 100!
ブロックから式を返す
-
if
,match
, 関数, ブロックは;
つけない式であれば戻り値として使用される
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());
}
// => if より: 1
// => 食品の識別: ホットドッグではありません
// => ブロックより: 3
// => 関数より: 7
Discussion