俺が知ってるrustのvec

vecについてまとめていきます。
ゆるく更新していきます。

# 先に参考
- [The Rust Programming Language 日本語版](https://doc.rust-jp.rs/book-ja/title-page.html)
教科書。親の顔よりみた。口癖移った。
- [rustのアドレス値と各要素の仕様確認](https://qiita.com/kahirokunn/items/bbde6dc6e649df68358b)
アドレス放出できることは知らなかった
- ~~[知ってた](https://dic.nicovideo.jp/a/%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%9F)~~
vecの記事なんで今更何が面白いんだってことぐらい知ってた。

## とりあえずこれは知ってた
```rust
fn main() {
    let mut v = Vec::new();
    v.push(0);
    v.push(1);
    v.push(2);
    println!("{:?}", v);
}
```
```
[0, 1, 2]
```

mut(可変)にしてpushする方法やねん。
ただ、サイズが何となくわかっているなら、`Vec::with_capacity`が使えます。
説明は省きますが、あらかじめ要素数を指定しておくと早くなります。

:::note

with_capacityを用いても、サイズは可変です。
あくまでパフォーマンスの改善につながるのです。メモリの割り当て方によるものです。
:::

```rust
fn main() {
    let mut v = Vec::with_capacity(3);
    v.push(0);
    v.push(1);
    v.push(2);
    println!("{:?}", v);
}
```
```
[0, 1, 2]
```

注意する点は、vecも配列同様、型が固定です。
Enumを使えば表現できる型が増えますが、それは別の話ってことで。
つまり、こういうのはダメ！〇刑！　ってことです。

```rust
fn main() {
    let mut v = Vec::new();
    v.push(0);
    v.push(1);
    v.push('２');
    println!("{:?}", v);
}
```
```
error[E0308]: mismatched types
    --> src\main.rs:5:12
     |
3    |     v.push(0);
     |     -      - this argument has type `{integer}`...
     |     |
     |     ... which causes `v` to have type `Vec<{integer}>`
4    |     v.push(1);
5    |     v.push('２');
     |       ---- ^^^^ expected integer, found `char`
     |       |
     |       arguments to this method are incorrect
     |
```
文字が入っているから怒られてしまいました。残念。
逆にこれもNG

```rust
fn main() {
    let mut v = Vec::new();
    println!("{:?}", v);
}
```
```
error[E0282]: type annotations needed for `Vec<T>`
 --> src\main.rs:2:9
  |
2 |     let mut v = Vec::new();
  |         ^^^^^
  |
help: consider giving `v` an explicit type, where the type for type parameter `T` is specified
  |
2 |     let mut v: Vec<T> = Vec::new();
  |              ++++++++

For more information about this error, try `rustc --explain E0282`.
```
型がわがんねって、言われましたね。 言われた通りに直せばよいのです。

```rust
fn main() {
    let mut v: Vec<i32> = Vec::new();
    println!("{:?}", v);
}
```

まぁ...まさかと思いますが
「エラーは`Vec<T>`って書いてあるんだから、
```rust
fn main() {
    let mut v: Vec<T> = Vec::new();
    println!("{:?}", v);
}
```
だろ？」なんて言わないでくださいね。
[ジェネリクス](https://doc.rust-jp.rs/rust-by-example-ja/generics.html)の説明が必要になって大変なんですから。(だれも言ってない...よね？)

## マクロ？なにそれ
こっからちょっと本題に入る

```rust
fn main() {
    let v = vec![0, 1, 2]
    println!("{:?}", v);
}
```
```
[0, 1, 2]
```

`!`はマクロという機能です。　これは、端的に言えばコンパイルする前にコードを書き換えてくれる優れものです。　このコードはおそらく
```rust
let v = {
    let mut v = Vec::with_capacity(3);
    v.push(0);
    v.push(1);
    v.push(2);
    v
};
```
というコードに変換されるはずです。

:::note
ちなみに、`{}`は式の一つです。　スコープ分けられます。　うへー便利な時代になったねぇ。
:::

ちなみにこのvec!マクロ、結構有能で
```rust
fn main() {
    let v = vec![0; 3]
    println!("{:?}", v);
}
```
```
[0, 0, 0]
```

0が3つで初期化されましたね。
これは通常の配列でも使えるテクニックですが、こんな感じに初期値を決めて楽に作ることもできます。ﾔｯﾀﾈ!

### 俺が知ってるvec!マクロの欠点

さて...便利ですね。で済ませたかったのですが、少し話しておかなければいけないことがあります。

このマクロ、**cloneトレイトが実装されている必要があるのです。**
トレイトとは、簡単に例えるとこうです！
「普通自動車免許を持つ者は、技量はともあれ普通自動車を運転できる」
つまり、免許みたいなものです。　これがないと技量の有無関係なしにクローン出来ないのです。
とにかく、cloneトレイトが実装されいている型でないとvec!マクロは使えない、そう解釈しておきましょう。　え？今使っている変数が実装しているトレイトを知りたいって？
うーん...知らね！（基本型はcloneトレイトの上位互換であるcopyトレイトが実装されています。ほかにも説明すると長くなってしまいますでの、ここでは割愛します。ご了承くださいな）

:::note warn
トレイトがわからないならこの記事はここまで見れば十分です。これ以上はvecに関する内容から外れますので...
:::

**しかしこれが、災いを起こすことがあります。参照カウンタRc・Arcの時です。**

これらのクローンは参照を返します。（実態・中身のコピーをしてくれない）
なので、このコードは端的に言いましょう。「意味を持ちません！残念！」

```rust
use std::rc::Rc;

fn main() {
    let v = vec![Rc::new(0); 3];
    println!("{:?}", v);
}
```
```
[0, 0, 0]
```

「は？なんで意味を持たないの？　0が三つ並んでんじゃないか。」
その0、すべて別物の変数ですか？　まさか一つずらしたらすべてずれるなんてことありませんよね？


<details><summary>「知っておこう」</summary>

今日は、参照カウント変数を三つ入れた配列のうち、一つの数字を変えたらどうなるかについて、知っておこう（早口）

```rust
use std::{cell::RefCell, rc::Rc};

fn main() {
    // vecを宣言する
    // rcの中身は普通不変である。そのためRefCellを使って
    // 可変値にできるようにした。
    let v = vec![Rc::new(RefCell::new(0)); 3];
    // borrow_mutを残すとtwo borrowになってエラーになる。
    // これはmut参照を一つしか置けないのと同じことである。
    // なので、スコープを分け、このスコープ内のみで有効にする必要がある。
    {
        // アドレスをクローンする。　こうしないと書き換えれない。
        let i = Rc::clone(&v[0]);
        // borrow_mut mut権限をくだしゃい！
        let mut i = i.borrow_mut();
        // 変えてしまおうこんなもの
        *i = 3;
    }
    // println!マクロのデバック表示では表現できないのでforで手動
    for i in v {
        let i = Rc::clone(&i);
        // mutは不要なので普通にもらってくる
        let i = i.borrow();
        // いざ、表示！
        println!("{}", i);
    }
}
```
```
3
3
3
```
うーーーーん...じゃぁ！
(終)

---

</details>

では、ポインタを表示して視覚化してみましょう。
```rust
use std::rc::Rc;

fn main() {
    let v = vec![Rc::new(0); 3];
    println!("{:p}", v[0]);
    println!("{:p}", v[1]);
    println!("{:p}", v[2]);
}
```
```
0x21cb2a3ff00
0x21cb2a3ff00
0x21cb2a3ff00
```

なんてことだ、~~もう助からないゾ❤~~すべてが同じアドレスじゃないか。

ちなみにboxとか別のcloneが実装された型にすると
```rust
fn main() {
    let v = vec![Box::new(0); 3];
    println!("{:p}", v[0]);
    println!("{:p}", v[1]);
    println!("{:p}", v[2]);
}
```
```
0x18394eec400
0x18394eec420
0x18394eec3e0
```
ちゃんとアドレスがずれてますわね。さすがですわ。

これに関しては、次の「イテレーター」を使ったり、forで頑張ればなんとかなります。

## イテレーターは知らなかった
javaのデザインパターンを見ていて「なんやねんこれ何の役に立つんや」ってずっと思ってた。
やっと理解したよ。やったね。

```rust
fn main() {
    let v:Vec<i32> = (0..3).collect();
    println!("{:?}", v)
}
```
```
[0, 1, 2]
```
まず秒で突っ込みたいのは型を指定しているところです。
だって右みりゃわかるじゃん。　って思いません？
思わない方はもう少し下にスクローール！

このcollectっていうのがどうやら頻繁に型を指定しなきゃいけないものの一つらしいです。　というのもそもそもcollectが、`Vec`以外にも適用できるかららしい。
（ここら辺はそのうち書きます多分）

それ以外の点を一つ一つ解読していきましょう。

### Range()は知ってた

`(0..3)`はどっかで見覚えのある表現です。
```py
for i in Range(0,3):
    print(i)
```

こいつです。　pythonで見ないことはないほど出てくる奴です。
Rangeというのはrustにもあって、それの表現方法が`(..)`って書き方です。
例えば`(0..4)`の場合、0,1,2,3 という4つの数字がイテレーター形式で表現されるわけです。

### じゃあイテレーターってなんだよ！　
汎用的な言語でイテレーターなしとイテレーター有りを比べてみましょう。
```java
// イテレーターなし
for(int i=0; i<3; i++) {
    println(i);
}
```
実際のこのコードが動く言語を知らないのですが、
想定している出力はこうです！
```
0
1
2
```
イテレーターがある場合、
```java
while(iter.hasNext()) {
    println(i.next());
}
```
こんな感じになります。　実装を書いてないので、このコードは動きませんがね...
例えば紙芝居です。　next()メソッドは紙芝居の次のページに移ります。
紙芝居が終わっているか（最後のページを過ぎたか）はhasNext()が伝えてくれます。
これらはiterという変数が持つ"状態"によって管理されるわけです。

```rust
struct iter {
    source: &Vec<_>
    index: usize,
    hasNext: bool,
}
```
これは簡易的に表現した、「状態を持つ構造体」です。　まず、sourceには元の配列、indexには今見ているページ（ポインタ）、そしてhasNextは次があるかどうかを示すわけです。

これにメソッド「next」を実装すればいいのです。　どういうメソッドにすればいいでしょうか？
コードは書きませんが、
- 今ページが指す値を返す
- indexをインクリメントする
- indexがsource.lenより多いならhasnextをfalseに変更する

図にするとこんな感じ
![fig1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893008/742f859e-2ea3-524b-2317-43f4f1cf640b.png)

左が配列だと思ってください。　ポインタはイテレーターのことで、上でいうindexの値です。
コードに直すなら
```rust
iter.index = 1;
&v[iter.index];
```
こんな感じです。

イテレーターの中身はここまでにして、とにかく「順番に何かを行う」という操作をするにはこのイテレーターとかいう機能は大変有能なわけです。~~知　ら　な　か　っ　た。~~

例えば`for_each`

```rust
fn main() {
    (0..3).for_each(|x| {
        println!("{}", x);
    });
}
```
```
0
1
2
```
forのイテレーターバージョンです。　多言語だといろいろメリットがありますが、rustだと
「（実質）一行でforが表現できる」などですかね。
ただし、rustは標準でforがイテレーター専用なので...🤔
と勝手に思っていますね。　（それいっちゃpyもそう）

今サラッと出てきた`|x| {}`というのはいわゆる無名関数とかいう奴です。
そしてfor_eachはコールバック関数なわけです。
javascriptとかでよく見た光景ですね。
簡単にコードにすると

```rust
fn for_each(&self, func: fn(T)) {
    for i in &self {
        func(i);
    }
}
```

こんな感じです。　引数selfはpythonなどと同様なので置いといて...
fn(T)を受け入れる引数funcは、書いてある通り関数を受け入れるわけです。
引数funcは変数funcであり、変数funcは関数funcなわけです。なので実行できます。

コールバック関数については、jsとかpythonとかやっていればわかると思います。
c++からの方は関数ポインタを使うらしいです。javaは関数テンプレートらしいです。　わたしゃしらん。

それと同時に出てくるのがこの無名関数こと「クロージャ」なわけです。

ほかにも
```rust
fn main() {
    (0..10).filter(|x| x % 2 == 0).for_each(|x| {
        println!("{}", x);
    });
}
```
filterの中身は `x%2==0` 。これはboolを返す式ですね。偶数ならtrueになるわけです。
trueのみを取ってくれるイテレーターです。なのでこれの出力は
```
0
2
4
6
8
```
となるわけです。
ほかにも
```rust
use std::rc::Rc;

fn main() {
    let x: Vec<_> = (0..3).map(|_| Rc::new(0)).collect();
    x.into_iter().for_each(|x| {
        println!("{:p}:{}", x, x);
    });
}
```
```
0x17101b84380:0
0x17101b84040:0
0x17101b84060:0
```

唐突にやってくるのは本題です。　まずvecとクロージャの引数が_(アンダーバー)になりました。
これは使わねぇこんなんって言ってます。それだけです。
型の指定も、あくまで`Vec`であることが重要であり、その中身はどうでもいい（予測可能）ということだそうです。

次にmapです。　これは一見for_eachのように見えますが、戻り値（今回は`Rc::new(0)`)で新しいイテレーターが作られるというものです。　単純に値をずらしたり、二乗にしてみたりすることができます。

```rust
fn main() {
    (0..4)
        .map(|x| 2_i32.pow(x as u32))
        .for_each(|x| println!("{}", x));
}
```
```
1
2
4
8
```
数値は`_i32`と置くだけで型を表現できるらしいです。　ｼﾗﾝｶｯﾀｰ!
powは累乗ですね。引数が`u32`、つまり符号なしです。今回は`as`で型を変換（キャスト）してます。 

mapについて理解できました。　into_iter()はイテレータを返すメソッド！

### ヨシ、本題だ！！！
先の復習です。まずvec!マクロはcloneによって実装されるので
```rust
use std::rc::Rc;

fn main() {
    let v = vec![Rc::new(0); 3];
    println!("{:p}", v[0]);
    println!("{:p}", v[1]);
    println!("{:p}", v[2]);
}
```
```
0x21cb2a3ff00
0x21cb2a3ff00
0x21cb2a3ff00
```
という、同じアドレスを指す意味のない配列が出てきます。
これの解決方法は何でしょうか？
簡単です。map使いましょう。

```rust
use std::rc::Rc;

fn main() {
    let x: Vec<_> = (0..3).map(|_| Rc::new(0)).collect();
    x.into_iter().for_each(|x| {
        println!("{:p}:{}", x, x);
    });
}
```
```
0x17101b84380:0
0x17101b84040:0
0x17101b84060:0
```

ね？アドレス変わってるでしょ？

mapはクローンを使ってない（一々newしてくれる)から、アドレスが変わります。
ゆえに実体も変わります。　

これが、俺の知ってるrustのvecでした。　現場からは以上です、僕は右に帰ります。失礼します。

（←おうち）
（中山→）
（秋葉原→）
（どっかの本社→）