The Rust Programming Languageを読み進める（3章）

# はじめに

The Rust Programming Languageを頭から読み進めてみる。読みながら要点をまとめていった記事です。

* [The Rust Programming Languageを読み進める（1〜2章）](https://qiita.com/yktooo/items/df17496b38b1b5c49aba)

# 3章：一般的なプログラミングの概念
## 3.1章：変数と可変性
https://doc.rust-jp.rs/book-ja/ch03-01-variables-and-mutability.html
```rust
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`は、内部可変性があり変更可能なパターンあり
```rust
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
```
* シャドーイングを繰り返しているコード
* シャドーイングによる和算が終われば、変数は不変に戻る

```rust
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章：データ型
https://doc.rust-jp.rs/book-ja/ch03-02-data-types.html
### 数値・文字列
```rust
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`型はユニコードで管理

### 配列・タプル
```rust
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つの変数に分配
```rust
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章：関数
https://doc.rust-jp.rs/book-ja/ch03-03-how-functions-work.html
### 基本的な使い方
```rust
fn main() {
    func_a(5, 'h');
}

fn func_a(value: i32, unit_label: char) {
    println!("Output: {}{}", value, unit_label);
}
```
```
Output: 5h
```
* 関数名はスネークケースで定義
* 関数の仮引数の型は、宣言が必要

### 戻り値・式と文
```rust
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章：コメント
https://doc.rust-jp.rs/book-ja/ch03-04-comments.html

略

## 3.5章：制御フロー
### if-else文
```rust
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式
```rust
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
```rust
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
```rust
fn main() {
    let mut number = 3;
    
    while number != 0 {
        println!("{}!", number);
        number -= 1;
    }
    
    println!("LIFTOFF!!!");
}
```
```
3!
2!
1!
LIFTOFF!!!
```

### for
```rust
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
```
特記事項なし