はじめに
The Rust Programming Languageを頭から読み進めてみる。読みながら要点をまとめていった記事です。
3章:一般的なプログラミングの概念
3.1章:変数と可変性
fn main() {
let mut x = 5;
println!("The value of x is: {}", x);
x = 6;
println!("The value of x is: {}", x);
const MAX_POINTS: u32 = 100_000;
println!("The value of MAX_POINTS is: {}", MAX_POINTS);
}
The value of x is: 5
The value of x is: 6
The value of MAX_POINTS is: 100000
-
mut
を外すとコンパイルエラーが発生 -
mut
を外す=値が不変であることをコンパイラが担保 -
const
は3桁毎に区切り、定義されたスコープ内でずっと有効- 型は常に注釈が必要
-
const
とlet
での宣言は異なる-
const
は、コンパイル時定数と書き換え不可 -
let
は、内部可変性があり変更可能なパターンあり
-
fn main() {
let x = 5;
let x = x + 1;
{
let x = x * 2;
println!("The value of x in the inner scope is: {}", x);
}
println!("The value of x is: {}", x);
}
The value of x in the inner scope is: 12
The value of x is: 6
- シャドーイングを繰り返しているコード
- シャドーイングによる和算が終われば、変数は不変に戻る
fn main() {
let s = "test test";
println!("s is: {}", s);
let s = s.len();
println!("s is: {}", s);
}
s is: test test
s is: 9
- 文字型から数字型にシャドーイングしている例
- 1回目に
let mut s
で宣言し、let s = s.len();
またはs = s.len();
と定義すると、警告やエラーが発生
3.2章:データ型
数値・文字列
fn main() {
let sum = 5 + 10;
println!("sum is {}", sum);
let difference = 95.5 - 4.3;
println!("difference is {}", difference);
let product = 4 * 30;
println!("product is {}", product);
let quotient = 56.7 / 32.2;
println!("quotient is {}", quotient);
let floored = 2 / 3;
println!("floored is {}", floored);
let remainder = 43 % 5;
println!("remainder is {}", remainder);
let boolean = false;
println!("boolean is {}", boolean);
let heart_eyed_cat = '😻';
println!("heart_eyed_cat is {}", heart_eyed_cat);
}
sum is 15
difference is 91.2
product is 120
quotient is 1.7608695652173911
floored is 0
remainder is 3
boolean is false
heart_eyed_cat is 😻
- 整数型の基準は
i32
、浮動小数型の基準はf64
- 文字
char
型はユニコードで管理
配列・タプル
fn main() {
let tup1 = (500, 6.4, "apple");
let (x, y, z) = tup1;
println!("The values of tup1: {}, {}, {}", x, y, z);
let tup2: (i32, f64, &str) = (500, 6.4, "apple");
let five_hundred = tup2.0;
let six_point_four = tup2.1;
let apple = tup2.2;
println!("The values of tup2: {}, {}, {}", five_hundred, six_point_four, apple);
}
The values of tup1: 500, 6.4, apple
The values of tup2: 500, 6.4, apple
- タプル型は、複数の型の要素を持てる複合型
-
変数名.0
のように、ピリオドで直接アクセス可能 -
let (x, y, z) = tup;
の書き方は、1タプルを3つの変数に分配
fn main() {
let a = [1, 2, 3, 4, 5];
let b: [i32; 5] = [1, 2, 3, 4, 5];
let c = [3; 5];
println!("The values of a: {:?}", a);
println!("The values of b: {:?}", b);
println!("The values of c: {:?}", c);
println!("The first value of a: {}", a[0]);
}
The values of a: [1, 2, 3, 4, 5]
The values of b: [1, 2, 3, 4, 5]
The values of c: [3, 3, 3, 3, 3]
The first value of a: 1
- 配列もタプルと同様に複合型であるが、全要素が同じ型である必要あり
-
Rustの配列は固定長なので、変更は不可
- 変更が予想される場合はベクタ型を使用
3.3章:関数
基本的な使い方
fn main() {
func_a(5, 'h');
}
fn func_a(value: i32, unit_label: char) {
println!("Output: {}{}", value, unit_label);
}
Output: 5h
- 関数名はスネークケースで定義
- 関数の仮引数の型は、宣言が必要
戻り値・式と文
fn main() {
let x = func_b(5);
println!("The value of x is: {}", x);
let y = {
let x = 3;
x + 1 // ";"を付けるとエラー
};
println!("The value of y is: {}", y);
}
fn func_b(x: i32) -> i32 {
x + 1 // ";"を付けるとエラー
}
The value of x is 6
The value of y is: 4
- Rustは式ベースの言語で、セミコロンが無いと式になり値を返す
- 一方でセミコロンが付くと文になり、処理を実行するが値は返さない
- Cで使える
x = y = 6
のような書き方は許さないため、let x = (let y = 6);
はエラーが発生
3.4章:コメント
略
3.5章:制御フロー
if-else文
fn main() {
let number = 6;
if number % 4 == 0 {
println!("number is divisible by 4");
} else if number % 3 == 0 {
println!("number is divisible by 3");
} else if number % 2 == 0 {
println!("number is divisible by 2");
} else {
println!("number is not divisible by 4, 3, or 2");
}
}
number is divisible by 3
- Rustのif文は括弧が不要
- いずれの分岐先でも戻り値の型は同一である必要あり
let文内でのif式
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("The value of number is: {}", number);
}
The value of number is: 5
- 別変数での評価結果に基づいて、変数に代入が可能
loop
fn main() {
let mut count = 0;
'counting_up: loop {
println!("count = {}", count);
let mut remaining = 10;
loop {
println!("remaining = {}", remaining);
if remaining == 9 {
break;
}
if count == 2 {
break 'counting_up;
}
remaining -= 1;
}
count += 1;
}
println!("End count = {}", count);
}
count = 0
remaining = 10
remaining = 9
count = 1
remaining = 10
remaining = 9
count = 2
remaining = 10
End count = 2
-
loop
はシングルクオテーションでラベルを付与可能 - 内部の
'counting_up
に到達したら、外側のloop
から脱出している- 見慣れないが、ただのラベルと思えば良い
while
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("LIFTOFF!!!");
}
3!
2!
1!
LIFTOFF!!!
for
fn main() {
let a = [10, 20, 30];
let mut index = 0;
// whileでイテレーション
while index < 3 {
println!("the value is: {}", a[index]);
index += 1;
}
// forループでイテレーション
for element in a {
println!("the value is: {}", element);
}
}
the value is: 10
the value is: 20
the value is: 30
the value is: 10
the value is: 20
the value is: 30
特記事項なし