Rustで勘違いしていたこと3選 🏄🌴 【100 Exercises To Learn Rust 🦀 完走記事 🏃】


[100 Exercises To Learn Rust](https://rust-exercises.com/) を題材に　[Qiita Engineer Festa 2024 投稿マラソン](https://qiita.com/official-campaigns/engineer-festa/2024) に参加していました！

https://qiita.com/namn1125/items/bd1b4cd028874189a3c1

7月17日に仮置きを残しながら投稿したのち、 **ようやく全記事完成しました**！ ので、その記念として、色々話したいと思います！<font color="#bbbbbb">(え、7/17ってもう3週間前...？！)</font>

目次

- [全記事一覧](#%E5%85%A8%E8%A8%98%E4%BA%8B%E4%B8%80%E8%A6%A7)
- [100 Exercises To Learn Rustを完走した感想](#100-exercises-to-learn-rust-%E3%82%92%E5%AE%8C%E8%B5%B0%E3%81%97%E3%81%9F%E6%84%9F%E6%83%B3)
  - [100 Exercisesの魅力](#100-exercises%E3%81%AE%E9%AD%85%E5%8A%9B)
    - [1. そこそこの長さ](#1-%E3%81%9D%E3%81%93%E3%81%9D%E3%81%93%E3%81%AE%E9%95%B7%E3%81%95)
    - [2. 無理のない学習順序](#2-%E7%84%A1%E7%90%86%E3%81%AE%E3%81%AA%E3%81%84%E5%AD%A6%E7%BF%92%E9%A0%86%E5%BA%8F)
    - [3. 各エクササイズ間に関連がある](#3-%E5%90%84%E3%82%A8%E3%82%AF%E3%82%B5%E3%82%B5%E3%82%A4%E3%82%BA%E9%96%93%E3%81%AB%E9%96%A2%E9%80%A3%E3%81%8C%E3%81%82%E3%82%8B)
    - [4. 効率よく"ミソ"を摂取できる](#4-%E5%8A%B9%E7%8E%87%E3%82%88%E3%81%8F%E3%83%9F%E3%82%BD%E3%82%92%E6%91%82%E5%8F%96%E3%81%A7%E3%81%8D%E3%82%8B)
- [Rustで今まで勘違いしていたこと3選](#rust%E3%81%A7%E4%BB%8A%E3%81%BE%E3%81%A7%E5%8B%98%E9%81%95%E3%81%84%E3%81%97%E3%81%A6%E3%81%84%E3%81%9F%E3%81%93%E3%81%A83%E9%81%B8)
  - [1. `Copy` は `Clone::clone` を...呼び出さなかった！](#1-copy-%E3%81%AF-cloneclone-%E3%82%92%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%95%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F)
  - [2. 不変参照は...実は不変ではなかった！](#2-%E4%B8%8D%E5%A4%89%E5%8F%82%E7%85%A7%E3%81%AF%E5%AE%9F%E3%81%AF%E4%B8%8D%E5%A4%89%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F)
  - [3. 値がスレッドを跨ぐには `'static` は...不要だった！](#3-%E5%80%A4%E3%81%8C%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89%E3%82%92%E8%B7%A8%E3%81%90%E3%81%AB%E3%81%AF-static-%E3%81%AF%E4%B8%8D%E8%A6%81%E3%81%A0%E3%81%A3%E3%81%9F)
- [所感](#%E6%89%80%E6%84%9F)

※ 前半は100 Exercisesの話題が中心です。早く勘違い3選を見たいという方は [こちら](#rust%E3%81%A7%E4%BB%8A%E3%81%BE%E3%81%A7%E5%8B%98%E9%81%95%E3%81%84%E3%81%97%E3%81%A6%E3%81%84%E3%81%9F%E3%81%93%E3%81%A83%E9%81%B8)

:::note
もう一本まとめ記事を書きましたので良かったら読んでみてください！

[【🙇 懺悔 🙇】Qiitanグッズ欲しさに1日に33記事投稿した話またはQiita CLIとcargo scriptを布教する的な何か](https://qiita.com/namn1125/items/8e552694b389c5b13b5e)
:::

# 全記事一覧

どの記事も熱量を込めて書きましたので読んでいただけたら恐悦至極です :bow:

- [【0】 準備](https://qiita.com/namn1125/items/bd1b4cd028874189a3c1)
- [【1】 構文・整数・変数](https://qiita.com/namn1125/items/c776768baec89b8a0438)
- [【2】 if・パニック・演習](https://qiita.com/namn1125/items/13870965e8273bc87bce)
- [【3】 可変・ループ・オーバーフロー](https://qiita.com/namn1125/items/4f57f8aede2f5201016f)
- [【4】 キャスト・構造体 (たまにUFCS)](https://qiita.com/namn1125/items/227ed5bbedbb775c5d27)
- [【5】 バリデーション・モジュールの公開範囲 ～ → カプセル化！～](https://qiita.com/namn1125/items/46721cceccbfa9ec3c7a)
- [【6】 カプセル化の続きと所有権とセッター ～そして不変参照と可変参照！～](https://qiita.com/namn1125/items/442de7798d49f777384c)
- [【7】 スタック・ヒープと参照のサイズ ～メモリの話～](https://qiita.com/namn1125/items/780d80e4340f0e34dbf6)
- [【8】 デストラクタ(変数の終わり)・トレイト ～終わりと始まり～](https://qiita.com/namn1125/items/7247edde3b6bd0b85b25)
- [【9】 Orphan rule (孤児ルール)・演算子オーバーロード・derive ～Empowerment 💪 ～](https://qiita.com/namn1125/items/e565713b423301a80c76)
- [【10】 トレイト境界・文字列・Derefトレイト ～トレイトのアレコレ～](https://qiita.com/namn1125/items/9060faee2965f23e0e3d)
- [【11】 Sized トレイト・From トレイト・関連型 ～おもしろトレイトと関連型～](https://qiita.com/namn1125/items/b68990712d379a3d6a49)
- [【12】 Clone・Copy・Dropトレイト ～覚えるべき主要トレイトたち～](https://qiita.com/namn1125/items/c6f34945f331c7229746)
- [【13】 トレイトまとめ・列挙型・match式 ～最強のトレイトの次は、最強の列挙型～](https://qiita.com/namn1125/items/6b2cc31d6a47f9ffaff6)
- [【14】 フィールド付き列挙型とOption型 ～チョクワガタ～](https://qiita.com/namn1125/items/6fe69d1cab6c7936c698)
- [【15】 Result型 ～Rust流エラーハンドリング術～](https://qiita.com/namn1125/items/698aafaf22ec4bfd1bde)
- [【16】 Errorトレイトと外部クレート ～依存はCargo.tomlに全部お任せ！～](https://qiita.com/namn1125/items/9dae7b728fa0668e4102)
- [【17】 thiserror・TryFrom ～トレイトもResultも自由自在！～](https://qiita.com/namn1125/items/d67006a29b7ff5d6148c)
- [【18】 Errorのネスト・慣例的な書き方 ～Rustらしさの目醒め～](https://qiita.com/namn1125/items/705829027661a38e4a4f)
- [【19】 配列・動的配列 ～スタックが使われる配列と、ヒープに保存できる動的配列～](https://qiita.com/namn1125/items/9c49fd4c08f3e61896c7)
- [【20】 動的配列のリサイズ・イテレータ ～またまたトレイト登場！～](https://qiita.com/namn1125/items/6e4dede789c6de97f396)
- [【21】 イテレータ・ライフタイム ～ライフタイム注釈ようやく登場！～](https://qiita.com/namn1125/items/9a1224abf733f29a980a)
- [【22】 コンビネータ・RPIT ～ :dragon: 「 `Iterator` トレイトを実装してるやつ」～](https://qiita.com/namn1125/items/27fe20f2d60803c94357)
- [【23】 `impl Trait` ・スライス ～配列の欠片～](https://qiita.com/namn1125/items/7601d0268293ce7fcf28)
- [【24】 可変スライス・下書き構造体 ～構造体で状態表現～](https://qiita.com/namn1125/items/a9acc7dc2ca7c4c55cc3)
- [【25】 インデックス・可変インデックス ～インデックスもトレイト！～](https://qiita.com/namn1125/items/bd43375362af10ea8b42)
- [【26】 HashMap・順序・BTreeMap ～Rustの辞書型～](https://qiita.com/namn1125/items/a2806cded12fa719a1cb)
- [【27】 スレッド・'staticライフタイム ～並列処理に見るRustの恩恵～](https://qiita.com/namn1125/items/5a4a09172834063268b1)
- [【28】 リーク・スコープ付きスレッド ～ライフタイムに技あり！～](https://qiita.com/namn1125/items/34a0aacd4d40f9234aef)
- [【29】 チャネル・参照の内部可変性 ～Rustの虎の子、mpscと `Rc<RefCell<T>>`～](https://qiita.com/namn1125/items/861e72dbb4b837508948)
- [【30】 双方向通信・リファクタリング ～返信用封筒を入れよう！～](https://qiita.com/namn1125/items/46f03de967d0de46737e)
- [【31】 上限付きチャネル・PATCH機能 ～パンクしないように制御！～](https://qiita.com/namn1125/items/d7ae8a205ee969339401)
- [【32】 `Send`・排他的ロック(`Mutex`)・非対称排他的ロック(`RwLock`) ～真打 `Arc<Mutex<T>>` 登場～](https://qiita.com/namn1125/items/eee890dc8672e975e70c)
- [【33】 チャネルなしで実装・Syncの話 ～考察回です～](https://qiita.com/namn1125/items/cc8bee3871b727e564e3)
- [【34】 `async fn`・非同期タスク生成 ～Rustの非同期入門～](https://qiita.com/namn1125/items/9c32b730a283ad76c891)
- [【35】 非同期ランタイム・Futureトレイト ～非同期のお作法～](https://qiita.com/namn1125/items/c840d48f8f558613ec10)
- [【36】 ブロッキング・非同期用の実装・キャンセル ～ラストスパート！～](https://qiita.com/namn1125/items/39c139da3f1f26264353)
- [【37】 Axumでクラサバ！ ～最終回～](https://qiita.com/namn1125/items/bae492f823fbe60e9974)
- 【おまけ1】 Rustで勘違いしていたこと3選 🏄🌴 【100 Exercises To Learn Rust 🦀 完走記事 🏃】 ← 本記事
- [【おまけ2】 【🙇 懺悔 🙇】Qiitanグッズ欲しさに1日に33記事投稿した話またはQiita CLIとcargo scriptを布教する的な何か](https://qiita.com/namn1125/items/8e552694b389c5b13b5e)

# 100 Exercises To Learn Rust を完走した感想

https://rust-exercises.com/

100 Exercises は比較的最近できたRustチュートリアルサイトです！100 Exercises自体の説明は[初回](https://qiita.com/namn1125/items/bd1b4cd028874189a3c1)に譲ります。(こちらでもそんなにしていないですが...)

マラソンの題材として完走した感想について、6月10日から約2ヶ月に渡り取り組んできたこともあり、エクササイズに対する思いを全て書き出すのは難しいですが、一言で表すと

『**:crab: 無理のないRust再入門 :crab:**』[^murinonai]

[^murinonai]: 本当にとんでもなくどうでもいい注釈ですが「[無理のないバイオ](https://dic.pixiv.net/a/%E7%84%A1%E7%90%86%E3%81%AE%E3%81%AA%E3%81%84%E3%83%90%E3%82%A4%E3%82%AA)」シリーズというのびハザ派生版のゲームが昔あってここの「無理のない」のニュアンスはこれ由来だったりします...他にもこの言葉が使われている例あったような気はするけど思い出せない...本当にどうでも良い注釈でした。

だったなぁと思います。つまり、筆者にとって「ちょうどいい内容」でした！

多くのRustaceanは至高の公式ドキュメント [The Rust Programming Language](https://doc.rust-jp.rs/book-ja/) (通称 TRPL) でRust入門するかと思います。TRPLは、Rustに留まらずコンピュータサイエンスにも足を突っ込んだ、かなり網羅的で詳細な入門書でとてもためになりますが、ただひたすら **長い** です。[Rustlings](https://github.com/rust-lang/rustlings) があれど全てを理解しながら進めるのは難しく、「とりあえず今は飛ばす」とした人が多いのではないでしょうか...？その後Rustプログラミングをしていく中で、我流で色々な知識を身につけていくわけです。

[100 Exercises To Learn Rust](https://rust-exercises.com/) はそんな我流で知識を身につけたRustacean(要は筆者)に復習の機会を与えてくれたのです！100 Exercisesの魅力を以下に挙げます。

## 100 Exercisesの魅力

### 1. そこそこの長さ

TRPLと比べて **長くない** です。決して短いとまではいいませんが(何しろマラソン記事書き上げには2ヶ月かかりましたから... :sweat_smile: )、内容を読み問題を解いていくだけならば、体感で[A Tour of Go](https://go-tour-jp.appspot.com/welcome/1) 1.5周分ぐらい(？)(適当)の、復習に最適な長さに感じました！

### 2. 無理のない学習順序

TRPLは公式ドキュメントである以上、トピックの「必要性」よりは「重要性」を優先した順序で書かれていたような気がします。一方で、100 Exercisesは「 **必要になったら** 」解説するというスタイルなのが特徴的でした。まるで定義していない知識は使ってはいけない大学数学のよう...

特に顕著だったのは配列・コレクションとトレイト(他言語でいうインターフェースの機能です)の登場タイミングでしょうか...？Rustの理解において **これがないと始まらないというのは、配列よりはどっちかというとトレイト** です。それを踏まえてなのかはわからないですが、TRPLは先にコレクションを扱っている一方、100 Exercisesでは **トレイトを先に** 扱っていました。他言語から新しくRustをやる人にはTRPLの並びの方が親切かもしれませんが、解説していない内容を極力避けて、必要になった時に解説を行う、という100 Exercisesのスタイルは、特に再入門者である筆者にとって読みやすい順番だったと思います。

### 3. 各エクササイズ間に関連がある

前節に関係した内容ですが、エクササイズ全体を通した題材が用意されており、「 **どういうシーン** でその回で扱っている機能を使うのか？」というのがわかりやすい内容だったと思います。

特に3章から7章では、「チケット管理システムを作る」という内容でした。各章で以下のような機能を作ります。

|  章   | 章名                                                                                        | 内容                                                                                                                   |
| :---: | :------------------------------------------------------------------------------------------ | :--------------------------------------------------------------------------------------------------------------------- |
|   3   | [Ticket v1](https://rust-exercises.com/100-exercises/03_ticket_v1/00_intro)                 | チケット構造体の定義。OOP的な内容を通して所有権・参照について扱う                                                      |
|   4   | [Traits](https://rust-exercises.com/100-exercises/04_traits/00_intro)                       | 主要なトレイトを扱い、チケット構造体への演算子オーバーロード等を行う                                                   |
|   5   | [Ticket v2](https://rust-exercises.com/100-exercises/05_ticket_v2/00_intro)                 | 列挙体を利用したバリデーション・回復可能なエラーハンドリング( `Option` 型や `Result` 型)を扱う                         |
|   6   | [Ticket Management](https://rust-exercises.com/100-exercises/06_ticket_management/00_intro) | 静的・動的配列やその他コレクション( `HashMap` 等 )・イテレータ等を用いた複数のチケットを管理できるシステムの構築を行う |
|   7   | [Threads](https://rust-exercises.com/100-exercises/07_threads/00_intro)                     | 並行処理により、チケット管理システムをサバクラ化する                                                                   |

「前章・前節までで作ったものを元に新たな機能を実装する」というスタイルは、「課題(必要性)が出てきたから取り組む」という学びやすい仕組みを生み出しており、これも取り組みやすい理由でした！

### 4. 効率よく"ミソ"を摂取できる

いわば「 :surfer: :surfer: 夏期講習 :island: :island: ！！！これだけは絶対に押さえておきたい要点n選！」みたいな感じで、解説対象がよく練られている印象でした。

例えば[4章](https://rust-exercises.com/100-exercises/04_traits/00_intro)のトレイトでは `Clone` ・ `Copy` ・ `Drop` 等絶対に押さえておきたいトレイトによくページが割かれていたり、[5章](https://rust-exercises.com/100-exercises/05_ticket_v2/00_intro) ではRust言語それ自体の仕様ではないのにも関わらず、デファクトスタンダードとなっており避けては通れない [thiserror](https://docs.rs/thiserror/latest/thiserror/) クレートを紹介したりと、Rustaceanを名乗るには知っておかねばならないであろう知識を効率よく確認できる内容となっていました！

...というわけで、復習のまとめとして、次節では筆者が恥ずかしながら勘違いしており今回のマラソンで知ることができた知識を3つ紹介したいと思います！

# Rustで今まで勘違いしていたこと3選

100 Exercisesを通して初めて知ったことは多々ありましたが、今回はその中でも厳選して3つ紹介します。

## 1. `Copy` は `Clone::clone` を...呼び出さなかった！

該当回: [【12】 Clone・Copy・Dropトレイト ～覚えるべき主要トレイトたち～](https://qiita.com/namn1125/items/c6f34945f331c7229746#%E8%A7%A3%E8%AA%AC-1)

Rustにおいて「(容易に)複製できる値(型)」は、プリミティブ型かデータクラスか...ではなくて **[`Clone`](https://doc.rust-lang.org/std/clone/trait.Clone.html) トレイトを実装しているか否か** ただその一言だけで表されます。筆者はこれに関連した記事を書いたことがありました。

拙著: [Rustにはシャローコピーがわからない](https://qiita.com/namn1125/items/2d84086394e97489776a)

Rustでは、`Clone` トレイトを実装している型の値 `v` に対して、その値を複製したい時は、 `v.clone()` と呼ぶことでディープコピーが可能です。

そして、この `Clone` トレイトに関連するトレイトとして、 [`Copy`](https://doc.rust-lang.org/std/marker/trait.Copy.html) トレイトというものがあります。こちらを付けた型は「 `.clone()` を付けなくても複製を行なってくれる」ようになります。また、 `Copy` トレイトを実装する型は、必ず `Clone` トレイトを実装している必要があります。

以上をまとめましょう。関係性はこうです。

- `Clone` トレイト実装型は `.clone()` で複製できる
- `Copy` トレイトという `.clone()` なしでも複製してくれるトレイトもとい機能がある
- **`Copy` は `Clone` を前提とする**

これらの事実より、筆者は勝手に「 `Copy` トレイトが付いていれば、複製時には `.clone()` を付けなくても裏で勝手に `.clone()` が呼ばれるんだろうなぁ」と思っていました。 **違いました**。

`Copy` トレイトはヒープ保存を必要としない型にしか付けられないのですが、`Copy` が付いている型が複製される場合は「スタック上のメモリの値がそのまま別なメモリに転記される」ように最適化されており、 **`.clone()` は呼ばれない** というのが真実でした...100 Exercisesで知るまで勘違いしていた... :flushed:

```rust:PoCコード beep!は2回出力される気がするが、一度しか出力されない
#[derive(Debug)]
struct Hoge(u32);

impl Clone for Hoge {
    fn clone(&self) -> Self {
        println!("beep!: {}", self.0);    

        Hoge(self.0)
    }
}

impl Copy for Hoge {}

fn main() {
    let h = Hoge(10);
    let h2 = h;
    
    dbg!(h);
    dbg!(h2);
    dbg!(h);
    h.clone();
}
```

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=de1113871471d8e7deb6aeae09c48dc7

上記拙著にて間違った説明をしてしまっていたのですが、今回修正を入れました :bow:

また関連して、勘違いしていたわけではなかったのですが、「 `Copy` を実装する型は [`Drop`](https://doc.rust-lang.org/std/ops/trait.Drop.html) トレイトを実装不可である」...というのも今回初めて知りました。

## 2. 不変参照は...実は不変ではなかった！

該当回: [【29】 チャネル・参照の内部可変性 ～Rustの虎の子、mpscと `Rc<RefCell<T>>`～](https://qiita.com/namn1125/items/861e72dbb4b837508948#%E5%86%85%E9%83%A8%E5%8F%AF%E5%A4%89%E6%80%A7)

勘違いというよりはよく知らなかったことになります。Rustの不変参照は名前通り値を変更できない参照ですが、 `RefCell` や `Mutex` を用いることで不変参照でも一時的に可変となることができます。これを **内部可変性** と言います。

筆者が知らなかったのは、不変参照が可変になれる分水嶺となる型 **[`UnsafeCell`](https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html)** の存在でした... **`RefCell` や `Cell` 、 `Rc` の内部では皆 `UnsafeCell` を使っている** らしいのです！

というのも、この `UnsafeCell` が [**ついていない不変参照は、コンパイラが最適化を施してくれる**](https://doc.rust-lang.org/std/cell/struct.UnsafeCell.html#:~:text=If%20you%20have,called%20%E2%80%9Cinterior%20mutability%E2%80%9D.) そうで、 **内部可変性を持つ不変参照が最適化されてしまわないためには、 `UnsafeCell` の使用が必須** そうなのです！

ちなみに不変参照ではなく「不変な値(構造体)」なら、内部に可変参照を持てば(屁理屈的に)内部可変？になれます。その事実より不変参照も同様だろう(ただ、知り得ないちょっと特殊な `unsafe` をしているんだろう)と思い込んでいたので、このことを知った時は目から鱗でした...

## 3. 値がスレッドを跨ぐには `'static` は...不要だった！ 

該当回:
- [【28】 リーク・スコープ付きスレッド ～ライフタイムに技あり！～](https://qiita.com/namn1125/items/34a0aacd4d40f9234aef#07_threads04_scoped_threads-%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97%E4%BB%98%E3%81%8D%E3%82%B9%E3%83%AC%E3%83%83%E3%83%89)
- [【33】 チャネルなしで実装・Syncの話 ～考察回です～](https://qiita.com/namn1125/items/cc8bee3871b727e564e3#sync-%E3%81%A8%E3%81%84%E3%81%86%E5%90%8D%E7%A7%B0%E3%81%AE%E8%BB%BD%E3%81%84%E8%80%83%E5%AF%9F)

こちらも勘違いというよりはよく分かっていなかった部分が鮮明になったという感じです。

Rustには、スレッド間で値を送り合えることを示す [`Send`](https://doc.rust-lang.org/std/marker/trait.Send.html) トレイトというものがあります。このマーカートレイトがついていない型は、レースコンディション等の問題でスレッド間転送ができません！そこまでは理解していました。

そして値(や参照)が普通の(←伏線です)スレッド間を跨ぐにはもう一つ条件がありまして、まさしくRustらしい話題なのですが、 **[`'static` ライフタイム](https://doc.rust-jp.rs/rust-by-example-ja/scope/lifetime/static_lifetime.html)を持つ**...言い換えると、「以降プログラム終了まで永遠に**生き続けられる**」必要があります。なぜなら「お互いのスレッドがいつまで生きているかはわからない」ためです！

そして大体の場合、片方のスレッドが持つ値への参照というのは、その参照を受け取った側のスレッドから見るといつまで生きているかわかりません。 `&'static T` ならプログラム終了時まで生きている保証がされているのですが、 **大体の場合参照は `'static` ではない** ので、「参照(あるいは `'static` ではない値)はスレッド間を跨げない」と考えていました。

```mermaid
sequenceDiagram
  participant T1 as スレッド1
  participant T2 as スレッド2
  activate T1
  activate T2
  T1->>T2: スレッド2の値を参照
  Note over T2: 先に終了
  deactivate T2
  T1-xT2: ぬるぽ！
  deactivate T1
```

そう理解していたので、 [`Sync`](https://doc.rust-lang.org/stable/std/marker/trait.Sync.html) トレイトという `Send` に似た並行処理の話題で出てくるトレイトが理解できませんでした。というのも、 `Sync` の定義が以下だからです...

> The precise definition is: a type T is Sync if and only if &T is Send. 

和訳: 「型 `T` が `Sync` であることと、その参照 `&T` が `Send` であることは同値である」

...:thinking: :thinking: :thinking:...？？？

「 **どうせスレッドを跨げない参照が `Send` でも意味を為さなくないか** ...？？？？ﾄﾞﾕｺﾄ...？！？」

ここで理解が止まってしまい、永遠に謎だったのですが、[第28回](https://qiita.com/namn1125/items/34a0aacd4d40f9234aef) に登場した **スコープ付きスレッド** [`std::thread::scope`](https://doc.rust-lang.org/stable/std/thread/fn.scope.html) がこの疑問を解決してくれました...

**スコープ付きスレッドなら、「そのスコープより長寿な参照」を渡せます**！

```rust:Rust
use std::thread;

fn main() {
    let v = String::from("Hello!");
    let r = &v;
    
    thread::scope(|scope| {
        scope.spawn(|| {
            println!("{} 1", r);
        });
        scope.spawn(|| {
            println!("{} 2", r); 
        });
    });
}
```

Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8a7c01287e4bfcf64bb700573ce2b2ee

「参照であるかどうか」と「転送可能であるか否か (`Send` か)」には関係がないことをこのメソッドのお陰で理解することができました！ (`'static` でない) **参照でもスレッドを跨いで良い** のです！

そう理解してから改めて「 `Sync` トレイトとはなんなのか...？」についても色々考えたのですが、それはぜひ[第33回](https://qiita.com/namn1125/items/cc8bee3871b727e564e3#sync-%E3%81%A8%E3%81%84%E3%81%86%E5%90%8D%E7%A7%B0%E3%81%AE%E8%BB%BD%E3%81%84%E8%80%83%E5%AF%9F)を読んでみてほしいです！

[【33】 チャネルなしで実装・Syncの話 ～考察回です～](https://qiita.com/namn1125/items/cc8bee3871b727e564e3#sync-%E3%81%A8%E3%81%84%E3%81%86%E5%90%8D%E7%A7%B0%E3%81%AE%E8%BB%BD%E3%81%84%E8%80%83%E5%AF%9F)

# 所感

100 Exercisesを通して、どうして自分がRustを好んでいるのか、また一段と理解できた気がします。

Rustが好きな理由は、「**特にトレイトを始めとした型に関する知識・説明だけでどのような挙動をするかを端的に伝えられる**」ことです。勘違い3選1つ目の `Copy` トレイトがわかりやすいですね。他言語だと新しい概念や構文を知る時に新しい文法や背景を知る必要があったりしますが、Rustでは「 **◯◯トレイトが実装されているから** 」「 **◯◯型が使われているから** 」の一言だけで理解できたり、伝えられたりすることが多いです！トレイトや型を通じて言語仕様を学べるという、この一貫したUIが好きなんじゃないかなと思います。

100 Exercisesを一通り完了させましたが、このエクササイズでは語られていないRustの深淵はまだまだたくさんあります、今後も精進していきたいです！(急な小並感)

ここまで読んでいただき、ありがとうございました！