Rustなんもわからん部~チュートリアルを読むPart2/n~

# Rustなんもわからん

Ruistなんも分かりません。わからないのでおててを動かしていきます。

今回もRustのチュートリアル(bookなるもの)を見ていきます。
英語版とその日本語訳版がありますが、今回は日本語訳版を見ていきたいと思います。

https://doc.rust-jp.rs/book-ja/

他の参考資料は以下の通りです。

https://www.rust-lang.org/ja/learn/get-started

https://doc.rust-jp.rs/rust-by-example-ja/

# チュートリアルを読む会

チュートリアルをひたすら読んで、内容をまとめていきます。
今回は4章までです。

## 3.一般的なプログラミングの概念

### 変数と可変性

基本的に、変数は不変で定義されるので、以下のようなコードだとエラーになります。

```rust
fn main() {
    let x = 5;
    println!("The value of x is: {}", x);     // xの値は{}です
    x = 6; // 不変変数で宣言しているのに変更しようとしている　
    println!("The value of x is: {}", x);
}
> Compiling variables v0.1.0 (file:///projects/variables)
> error[E0384]: cannot assign twice to immutable variable `x`
>               (不変変数`x`に2回代入できません)
```
エラー原因としては、`不変変数xに2回代入できない`というものです。不変であると宣言したら、本当に変わらないことをコンパイラが担保します。なので、どのように値が変化しているかを追跡する必要がなくなります。
しかしながら、変数には可変性が必要な場合があり、その場合は以前書いたように、`mut`をつけることで、可変変数であることを宣言できます。
```rust
fn main() {
    let mut x = 5;
    println!("The value of x is: {}", x);
    x = 6; // 可変変数と宣言したxなので、これでもエラーにならない。
    println!("The value of x is: {}", x);
}
```
これによって、先ほど出たエラーが出なくなります。

逆に、不変の変数ではなく、最初から定数として宣言することが出来ます。定数として宣言する場合は、`const`を用い、同時に型タイプの宣言も行わなければならないそうです。
```rust
const MAX_POINTS: u32 = 100_000
// constで定数であるという宣言
// :u32で、符号なし32bit整数型であるという宣言
// アンダースコアはあっても無視される？謎
```

#### 変数のシャドーイング

以下のコードを見てください。
```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);
        > The value of x in the inner scope is: 12
    }
    println!("The value of x is: {}", x);
    > The value of x is: 6
}
```
これが、変数のシャドーイングといわれるものです。 __同じ名前の変数を新しく宣言することで、前の変数を覆い隠す__ ということです。
また、その覆い隠す範囲に関しては、同じスコープ範囲内に限られるようです。今回であれば、コード真ん中の __{ }__ 内部を抜けたことで、xの値がもとに戻っています。

この方式の利点として、データ型についても可変性を持たせられるという点があります。
```rust
// エラーにならない
let spaces = "   ";
let spaces = spaces.len();

// エラーになる
let mut spaces = "   ";
spaces = spaces.len(); // これによって、データ型自体が変更されるので
```

### データ型

Rustにおける値は全て何らかのデータ型となっています。主にスカラー型と複合型の二種類があるそうです。

#### スカラー型

スカラーとは、単独の値を表します。主に、整数、浮動小数点、論理値、文字の四種類だそうです。

整数型には、u32(符号なし32bit整数)や、i8(符号付き8bit整数)などがあるそうです。usizeやisizeは64bitアーキテクチャであれば64bit型になるそうです。基準としてはi32が一般であり、普通最速になるそうです。

浮動小数点型には、f32とf64の二種類が基本型として存在しますが、一般にはf64が使われるそうです。(f32とほぼ同じスピードで精度が高いため)

数値演算は以下の通りです。
```rust
fn main() {
    // addition
    // 足し算
    let sum = 5 + 10;

    // subtraction
    // 引き算
    let difference = 95.5 - 4.3;

    // multiplication
    // 掛け算
    let product = 4 * 30;

    // division
    // 割り算
    let quotient = 56.7 / 32.2;
    let floored = 2 / 3; // Results in 0
                         // 結果は0

    // remainder
    // 余り
    let remainder = 43 % 5;
}
```
基本的には見たまんまですが、一部データ型による強制が働いています。
演算で変数の値を決める場合、同じ型同士の演算でないとエラーになるようで、例えば以下のようなコードだとエラーになります。
```rust
let difference = 5.0 - 14;

error[E0277]: cannot subtract `{integer}` from `{float}`
 --> src/main.rs:9:26
  |
9 |     let difference = 5.0 - 14;
  |                          ^ no implementation for `{float} - {integer}`
```
なので、計算の際はデータ型に十分注意する必要があると思います。

論理値型は、trueとfalseのみの、boolとして存在します。

文字型(char型)は、シングルクォーテーションで指定できます。(ダブルクォーテーションは文字列になるので別)ユニコードのスカラー値として表現されているようです。8章でまた詳細を説明するとのことです。

補足的な話になりますが、Rustは静的型付き言語であるので、コンパイル時に全ての変数の型が判明している必要があります。コンパイラが使用方法に基づいて型推論をしてくれるそうですが、複数の可能性がある場合は型アノテーションをつける必要があるそうです。

#### 複合型

複合型は、複数の値を一つの型にまとめることが出来る型であり、タプルと配列の二種類の基本的な形式があるそうです。

タプル型は、複数の型を一つの値としてまとめ上げられます。
```rust
fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
}
```

各要素にアクセスする場合は、以下の二通りの方法があるそうです。
```rust
// 一つ目
// タプル自体を破壊する形での取り出し
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("The value of y is: {}", y);

// 二つ目
// タプルからの直接取り出し
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
```

配列型は、タプル型とは異なり、同じ型の要素のみしかまとめることが出来ず、また配列長を変更することもできません。
```rust
// 配列の定義(3パターン)
let a = [1, 2, 3, 4, 5];

// データ型と配列長を宣言
let a: [i32; 5] = [1, 2, 3, 4, 5];

// [3,3,3,3,3]と同義
let a = [3; 5];

// 配列の要素へのアクセス
let a = [1, 2, 3, 4, 5];

// pythonのlistみたいにアクセスできる。
// 0から開始
let first = a[0];
let second = a[1];
```

特徴的な点としては、配列の長さを超える値を指定した場合、コンパイルは通りますが、実際にプログラムを実行するとエラーになって即時終了するそうです。以下のコードで5以上の値を入力するとこのようになるそうです。
```rust
use std::io;

fn main() {
    let a = [1, 2, 3, 4, 5];

    println!("Please enter an array index.");
           // 配列の何番目の要素にアクセスするか指定してください

    let mut index = String::new();

    io::stdin()
        .read_line(&mut index)
        .expect("Failed to read line");
              // 値の読み込みに失敗しました

    let index: usize = index
        .trim()
        .parse()
        .expect("Index entered was not a number");
        　　　// 入力された値は数字ではありません

    let element = a[index];

    println!(
        "The value of the element at index {} is: {}",
        // {}番目の要素の値は{}です
        index, element
    );
}

> thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 10', src/main.rs:19:19
> スレッド'main'は'範囲外アクセス: 長さは5ですが、添え字は10でした', src/main.rs:19:19
> でパニックしました
> note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
```

これは、パニックというRust用語であり、プログラムがエラーで終了したことを示します。
このパニックがあることで、無効なメモリへのアクセスを抑制しています。

### 関数

関数定義は、以下のようにfnキーワードで定義され、スネークケースによる命名が慣例だそうです。
```rust
fn main() {
    println!("Hello, world!");

    another_function();
}

fn another_function() {
    println!("Another function.");  // 別の関数
}
```
引数を設定する場合は、以下のように変数名とその型を宣言する必要があります。
```rust
fn main() {
    print_labeled_measurement(5, 'h');
}

fn print_labeled_measurement(value: i32, unit_label: char) {
    println!("The measurement is: {}{}", value, unit_label);
}
```

文と式についてです。ここはrustが式指向言語であるために重要な内容となっています。
文はセミコロンがつき値を返しませんが、式にはセミコロンがつかず、値を返します。
例えば、以下のような関数があったときに、エラーになるのはどちらでしょうか。
```rust
fn five() -> i32 {
    5
    5;
}
```
この関数は、呼ばれたときに、数字の5を返してほしいので、文で終わってしまっては値を返さないという挙動になり不適切です。
ですので、答えとしては`5`(セミコロンなし)となります。

### コメント

rustにおけるコメントは、`//`で表現されます。

### 条件分岐

rustにも条件分岐があります。例えば、以下のようなコードで用いられています。
```rust
fn main() {
    let number = 6;

    if number % 4 == 0 {
        // 数値は4で割り切れます
        println!("number is divisible by 4");
    } else if number % 3 == 0 {
        // 数値は3で割り切れます
        println!("number is divisible by 3");
    } else if number % 2 == 0 {
        // 数値は2で割り切れます
        println!("number is divisible by 2");
    } else {
        // 数値は4、3、2で割り切れません
        println!("number is not divisible by 4, 3, or 2");
    }
}
```
大体ほかの言語と同じような感じです。if自体は式になるので、以下のような使い方もできます。
```rust
fn main() {
    let condition = true;
    let number = if condition { 5 } else { 6 };
    // 式なので、変数の値として使用できる。

    // numberの値は、{}です
    println!("The value of number is: {}", number);
}
```

### ループでの繰り返し

rustには、`loop`と`while`、そして`for`の三つのループがあります。
まずは、`loop`についてです。これは、同じコードを延々と繰り返すものです。なので、breakによる終了が必要となりますが、その際loop自体に名前を付けておくことで、外側の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);
}
```
このように、loopの脱出はbreakで行えますが、その自由度は高いです。
それ以外にも、`continue`によって、次のループへ行くことも可能です。

whileは、loopに条件式を加えることが出来、条件式が真である間はループを継続することが出来ます。
```rust
fn main() {
    let mut number = 3;

    while number != 0 { // numberが0にならない限り継続
        println!("{}!", number);

        number -= 1;
    }

    // 発射！
    println!("LIFTOFF!!!");
}
```

forは、繰り返し範囲を指定して繰り返すことが出来ます。
```rust
fn main() {
    let a = [10, 20, 30, 40, 50];

    for element in a {
        println!("the value is: {}", element);
    }
}
```
ちなみに、逆順でfor文を回すこともできるそうです。
```rust
fn main() {
    for number in (1..4).rev() { // 3,2,1の順で繰り返す
        println!("{}!", number);
    }
    println!("LIFTOFF!!!");
}
```

## 4.所有権を理解する

rustにおける所有権という概念は、他の言語では見られない概念であり、この概念があるからこそ、メモリ管理が簡単になっているそうです。

https://doc.rust-jp.rs/book-ja/ch04-01-what-is-ownership.html

<details><summary>スタックとヒープに関して</summary>

gpt君に聞いてみました。
| 特徴  | スタック（Stack）  | ヒープ（Heap）     |
| --- | ------------ | ------------- |
| 構造  | LIFO（後入れ先出し） | 無秩序（ランダム配置）   |
| 管理  | 自動（スコープで解放）  | 所有権とライフタイムで管理 |
| 速度  | 高速           | 比較的遅い         |
| サイズ | 小さい          | 大きい           |
| 用途  | 値の固定サイズのデータ  | 可変サイズや動的なデータ  |

だそうです。
そして、関数を実行する際、以下の例ではxがサイズ固定ゆえにスタックに置かれるそうです。
```rust
fn main() {
    let x = 5;  // `i32` はサイズが固定なのでスタックに置かれる
    println!("{}", x);
}
```
以下の例では、stringの本体がヒープに、ポインタ、長さ、容量の情報がスタックに置かれるようです。
```rust
fn main() {
    let s = String::from("hello"); // `String` はヒープにメモリを確保
    println!("{}", s);
}
// スタック： [s の構造体（ポインタ, 長さ, 容量）]
// ヒープ：　["hello"]
```
どうしてこのようになっているかというと、従来の言語であれば、ヒープ領域にメモリ確保を行い、そしてその解放を行うのはプログラマーが手作業で実施していましたが、Rustではスタックにポインタ(というか所有者？)を置くことで、スコープが終了次第自動でヒープが解放されるようになっています。

？？？？？？？

従来言語とは異なり、ヒープのメモリ領域確保が、所有権と絡んで自動で行われるところが利点なんだと思います。よくわからないです。

参考資料

https://qiita.com/tsukasaI/items/5ea55f8b4e6d983590f8

https://keens.github.io/blog/2017/04/30/memoritosutakkutohi_puto/

</details>

### 所有権規則
所有権のルールとしては、以下の三つが挙げられていました。
- Rustの各値は、所有者と呼ばれる変数と対応している。
- いかなる時も所有者は一つである。
- 所有者がスコープから外れたら、値は破棄される。

### 変数スコープ

スコープとは、要素が有効になるプログラム内の範囲のことです。
```rust
{                      // sは、ここでは有効ではない。まだ宣言されていない
    let s = "hello";   // sは、ここから有効になる

    // sで作業をする
}                      // このスコープは終わり。もうsは有効ではない
```

### String型とchar型の違いから見る、メモリの扱い方

String型自体は、8章で詳しく議論するそうですが、ここでいったん使ってみます。例えば、こんな風に用いることが出来ます。
```rust
let s = String::from("hello");
```
これは、Stringモジュールのfrom関数を使って、"hello"という文字列からString型を宣言しています。
重要なのは、以下のコードが成立するということです。
```rust
let mut s = String::from("hello");
s.push_str(", world!"); // push_str()関数は、リテラルをStringに付け加える
println!("{}", s); // これは`hello, world!`と出力する
```
逆に、以下のコードはchar型を使ったコードですが、エラーになります。
```rust
let mut s = 'hello';
s.push_str(", world!"); 
println!("{}", s);

Compiling playground v0.0.1 (/playground)
error: character literal may only contain one codepoint
 --> src/main.rs:2:17
  |
2 |     let mut s = 'hello';
  |                 ^^^^^^^
```

この違いは、String型とchar型のメモリの使い方によるものです。
char型の場合、不変であるために高速に扱うことが出来ます。しかし、サイズの可変性が許されていない、詰まるところスタックに保管されているため、サイズが変更されるということが許されません。(メモリが事前確保されている以上に使うことが出来ない。)
逆に、String型は可変性を前提としており、ヒープ領域に文字列自体を、スタック領域にポインタ、長さと容量の情報を保管しています。文字列自体がヒープ領域に保管されているために、長さを後からいじるということが可能になっています。

つまり、保存領域が大きく分けてスタックかヒープかという特性によって、上記二つのコードが成立するかどうかが決まっています。

さて、ここでもう一つ問題となるのが、ヒープ領域のメモリをどうやって開放するかということです。
メモリ領域は、コード実行時にOSに要求され、終了時にはOSに変換する必要があります。
仮に手動で変換をしていた場合、メモリを解放するタイミング次第でエラーになったり、二回解放してしまったらエラーになったりと、エラーの大量発生が予想されます。これを解決するため、Rustでは、 ___メモリを所有している変数がスコープを抜けたら、メモリは自動的に変換される___ ようになっています。
これによって、メモリ解放を効率的に事故なく行えるようになっているそうです。

ここからは問題となりそうなサンプルコードを見てみます。
```rust
let x = 5;
let y = x;
```
上記のコードは、xもyも5として新しく変数を宣言するものになっています。これをstringでも実行するとこのようになります。
```rust
let s1 = String::from("hello");
let s2 = s1;
```
一見すると同じに見えますが、これらのコードは大きく異なっています。具体的には、二つ目のコードでは、 __s1は無効__ になります。
```rust
let s1 = String::from("hello");
let s2 = s1;

println!("{}, world!", s1);

rror[E0382]: use of moved value: `s1`
              (ムーブされた値の使用: `s1`)
 --> src/main.rs:5:28
  |
3 |     let s2 = s1;
  |         -- value moved here
4 |
5 |     println!("{}, world!", s1);
  |                            ^^ value used here after move
  |                               (ムーブ後にここで使用されています)
  |
  = note: move occurs because `s1` has type `std::string::String`, which does
  not implement the `Copy` trait
    (注釈: ムーブが起きたのは、`s1`が`std::string::String`という
    `Copy`トレイトを実装していない型だからです)
```
どういうことかというと、まずs1からs2のコピーでは、ヒープ領域の複製は行われず、string型のデータ(ポインタ、長さ、メモリサイズ)のみが複製されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806752/c91d2d9f-78b3-4741-a72e-4cfd5f97e234.png)

つまり、 __スタック型のみ__ がコピーされています。先ほどの整数型のコードでは、同様のコードを実行してもエラーにはなりません。なぜなら、スタック型に値そのものも存在するため、その値自体もコピーされることになるからです。(これは、スタック型に保存されるデータであれば、コピーしても十分高速なので、データ自体もコピーされるためだそうです。)
この理屈で、整数型や論理型、浮動小数点型、文字列型char、タプルはコピーによってデータ自体もコピーされます。

s1が無効になる理由としては、このままs1とs2が同じポインタを持つと、スコープを抜けた際にメモリ解放が二度行われてエラーになるからです。これを防ぐために、コンパイルの段階でs1を無効にしています。
所有権自体が移動している？、ようなものなので、ムーブという言われ方をしています。

ちなみに、ヒープ領域も併せて複製する場合は、cloneメソッドを用いればよいそうです。

### 所有権と関数

先ほどまでしていたムーブやコピーの話を、関数に持ってきます。
例えば、以下のようなコードを見てみます。
```rust
fn main() {
    let s = String::from("hello");  // sがスコープに入る

    takes_ownership(s);             // sの値が関数にムーブされ...
                                    // ... ここではもう有効ではない
    // println!("{}",s)はエラー　sにもう所有権がないから

    let x = 5;                      // xがスコープに入る

    makes_copy(x);                  // xも関数にムーブされるが、
                                    // i32はCopyなので、この後にxを使っても
                                    // 大丈夫

} // ここでxがスコープを抜け、sもスコープを抜ける。ただし、sの値はムーブされているので、何も特別なことは起こらない。
  //

fn takes_ownership(some_string: String) { // some_stringがスコープに入る。
    println!("{}", some_string);
} // ここでsome_stringがスコープを抜け、`drop`が呼ばれる。後ろ盾してたメモリが解放される。
  // 

fn makes_copy(some_integer: i32) { // some_integerがスコープに入る
    println!("{}", some_integer);
} // ここでsome_integerがスコープを抜ける。何も特別なことはない。
```
このコードでは、初めヒープ領域の"hello"の所有権をsが持っていますが、takes_ownershipに所有権がムーブされています。なので、関数実行後にsをprintしても、所有権がなくなっておりエラーになります。
つまりこのままでは、 __関数に一度渡した変数が使えない__ ということになってしまいます。これを防ぐための仕組みとして、参照と借用が存在します。

### 参照と借用

先ほど、関数に値をそのまま渡してしまうと、所有権自体を渡すこととなり、関数実行によって値が無効になるという話をしていました。それを解決するものとして、参照というものがあり、`&`で表現されます。
```rust
fn main() {
    let s1 = String::from("hello");

    let len = calculate_length(&s1);
    // &とすることで、参照渡しをしている。
    // s1がヒープ領域の所有権を失わない。

    // '{}'の長さは、{}です
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    // &で参照渡しをすることを宣言
    s.len()
}
```
このようにすることで、値を参照渡しすることができるそうです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806752/c988f0ce-3c65-4c7b-b7c7-506197450bdd.png)

ちなみに、参照している値を変更することはできないそうです。
```rust
fn main() {
    let s = String::from("hello");

    change(&s);
}

fn change(some_string: &String) {
    some_string.push_str(", world");
}
error[E0596]: cannot borrow immutable borrowed content `*some_string` as mutable
(エラー: 不変な借用をした中身`*some_string`を可変で借用できません)
 --> error.rs:8:5
  |
7 | fn change(some_string: &String) {
  |                        ------- use `&mut String` here to make mutable
8 |     some_string.push_str(", world");
  |     ^^^^^^^^^^^ cannot borrow as mutable
```
あくまで、値を渡せるだけ、ということですね。
変更可能な形で参照渡しをする場合は以下のようにすればいいそうです。
```rust
fn main() {
    let mut s = String::from("hello");

    change(&mut s);
    // &mut sで、可変な参照であるという宣言
}

fn change(some_string: &mut String) {
    some_string.push_str(", world");
}
```
ただし、同一スコープ内部で可変な参照はデータごとに一つだけ持てるようです。(不変な参照はいくつでも持てる？っぽい)
```rust
let mut s = String::from("hello");

let r1 = &mut s;
let r2 = &mut s;

println!("{}, {}", r1, r2);

Compiling ownership v0.1.0 (file:///projects/ownership)
error[E0499]: cannot borrow `s` as mutable more than once at a time
(エラー: 一度に`s`を可変として2回以上借用することはできません)
 --> src/main.rs:5:14
  |
4 |     let r1 = &mut s;
  |              ------ first mutable borrow occurs here
  |                    (最初の可変な参照はここ)
5 |     let r2 = &mut s;
  |              ^^^^^^ second mutable borrow occurs here
  |                    (二つ目の可変な参照はここ)
```
この仕組みによって、以下のようなデータ競合を防いでいます。
- 2つ以上のポインタが同じデータに同時にアクセスする。
- 少なくとも一つのポインタがデータに書き込みを行っている。
- データへのアクセスを同期する機構が使用されていない。

なので、例えば不変な参照をしている間に可変な参照をすることで、予想しないデータの変更が発生する、などの事態を防いでいます。

### スライス型

所有権のないデータ型として、参照以外にスライスが存在します。スライスによって、その中の一連の要素を参照できます。
例えば、こんなコードがあります。
```rust
fn main() {
    let mut s = String::from("hello world");

    let word = first_word(&s); // word will get the value 5
                               // wordの中身は、値5になる

    s.clear(); // this empties the String, making it equal to ""
               // Stringを空にする。つまり、""と等しくする

    // word still has the value 5 here, but there's no more string that
    // we could meaningfully use the value 5 with. word is now totally invalid!
    // wordはまだ値5を保持しているが、もうこの値を正しい意味で使用できる文字列は存在しない。
    // wordは今や完全に無効なのだ！
}

fn first_word(s: &String) -> usize {
    // stringに対して、最初の単語の長さを返す関数
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return i;
        }
    }
    s.len()
}
```
このコードは、文字列を入れて、その文字列中の最初の単語の長さをwordとして出力していますが、その後sがクリアされてしまっています。
wordには、sの文字列情報を常に反映した値が入っていてほしいですが、コード終了時にwordは5でsは空白となっており、両者の関係性が消滅しています。これを解決するのがスライスです。
スライス型は、&s[0..5]のようにすることで、参照先データの0番目から4番目までの値を参照するようになっています。例えば、以下のようになっています。
```rust
let s = String::from("hello world");

let world = &s[6..11];
```
この時、`hello world`という文字列はヒープ領域に保管され、sはそこへのポインタと長さ、データ容量をスタック型で保管しています。
worldというスライス型は、以下のように、スタック型で、始点へのポインタと長さを保持しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3806752/6811b48f-5148-4c2f-9624-7cc1cb08fd90.png)

このデータ型を使用することで、初めのコードのように、wordとsの関連性がなくなるといった事態をコンパイルの時点で防ぐことが出来ます。
例えば、文字列の中の最初の単語の長さを返す関数を以下のようにします。
```rust
fn first_word(s: &String) -> &str {
    let bytes = s.as_bytes();

    for (i, &item) in bytes.iter().enumerate() {
        if item == b' ' {
            return &s[0..i];
        }
    }
    &s[..]
}
```
こうすることで、s.clear()でエラーが出るようになります。
```rust
fn main() {
    let mut s = String::from("hello world");

    let word = first_word(&s);

    s.clear(); // error! （エラー！）

    println!("the first word is: {}", word);
}

Compiling ownership v0.1.0 (file:///projects/ownership)
error[E0502]: cannot borrow `s` as mutable because it is also borrowed as immutable
(エラー: 不変として借用されているので、`s`を可変で借用できません)
  --> src/main.rs:18:5
   |
16 |     let word = first_word(&s);
   |                           -- immutable borrow occurs here
   |                             (不変借用はここで発生しています)
17 | 
18 |     s.clear(); // error!
   |     ^^^^^^^^^ mutable borrow occurs here
   |              (可変借用はここで発生しています)
19 | 
20 |     println!("the first word is: {}", word);
   |                                       ---- immutable borrow later used here
                                                (不変借用はその後ここで使われています)
```
wordは不変参照ですが、clearが可変参照となっているのでエラーになる、ということです。

#### 補足　文字列リテラルはスライスである、とは？

以下のような説明がありました。

> 文字列は、バイナリに埋め込まれると話したことを思い出してください。今やスライスのことを知ったので、 文字列リテラルを正しく理解することができます。
> ```
> let s = "Hello, world!";
> ```
> ここでのsの型は、&strです: バイナリのその特定の位置を指すスライスです。 これは、文字列が不変である理由にもなっています。要するに、&strは不変な参照なのです。

シンプルに何を言っているかわからないので、gptに聞いてみました。その結果、
- 実行ファイル(バイナリ)中に、"hello world!"という文字列が物理的に埋め込まれている
- `s`は"hello world!"というデータへの参照を保持している
- strはUTF-8エンコードされた文字列のスライス

とのことです。つまり、文字列として変数を宣言していますが、実際にコンパイルしたファイルを実行する場合は、実行ファイル上にハードコードされた文字列の参照、という形で`s`が存在するということです。

### まとめ
- スタック領域とヒープ領域を併用している
- メモリ解放は自動で行われる
- 値の参照によって所有権の移動なしに値を活用できる

# 全体まとめ

今回も、チュートリアルを読んで終了しました。
これまでpythonしか触ったことがなかったので、プログラミングにおけるメモリとかの話を何も考えたことがなく、所有権周りの概念を理解するのに手間取りました。
Rustをやる場合は一生ついて回るようなので、今後のチュートリアルを進めていくうちに慣れていと思っています。