Rustにふれたよ


こんにちは〜〜〜〜🎸
この記事はNE Advent Calendar 2022のカレンダー1枚目１１日目の記事です

Rustにふれました。すごかったです。
ツールの使い心地の感動と実際理解を深めようとしたときの奥の深さに頭を抱えました。
どこかの誰かのちょっとしたきっかけぐらいになってくれたら幸いです。

# はじめに
Rustについて触ってみようと思ったのは **WEB+DBvol.131の「Rust入門」** を読んだのがきっかけです。

個人的にはとっかかり的にはめちゃくちゃvol.131の説明がわかりやすかったのでおすすめです。

なので、今回の記事はWEB+DBvol.131と公式サイトのチュートリアルで学んでこととをもとに書いていこうと思います

# Rustの世界に触れてみる

Rust製のコマンドラインがこの世には色々あるようで、今回がRust製grep(rg)コマンドで体感してみる。(インストール手順は割愛)

ってことで、
ここにね1GBのテキストデータがあるでしょ？
![スクリーンショット 2022-12-10 13.46.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212395/cabf1f74-5e2a-4c07-86b1-c26319ecdf18.png)


実際このなかにはたくさんの「aaaa」って文字がはいってるの

だけど、１個だけ「test」って文字が入っちゃってて何行目にあるのかを知りたいよね

標準のgrepとRust製のgrepで比較してみよう！

**1GBのデータから値を抜き出す速度の比較**

![ezgif.com-gif-maker (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212395/7255faea-4fb1-d052-bbf9-b0c7832c9e0a.gif)

**結果**
* grep → 7.14s
* rg   → 0.06s

**めちゃくちゃ早〜〜〜〜〜〜い！！！！！これがRustか！！！！！！！**
ってことでモチベが上がったところで、詳しく知っていく👇👇👇


# Rustってなぁに？

1. Rustはね、**コンパイル型言語**っていう**処理速度の速さ**に定評がある種類の１つでね。おんなじお友達にはC言語やJavaもいるんだよ。(参考記事がめちゃくちゃ分かりやすかったです)
参考：https://qiita.com/tomokichi_ruby/items/73b0e7924a9f83fe45c6
1. Rustはね、**所有権**っていう特有のメモリ管理の方法が特徴なんだよ。所有権があることは所有者もあってそれはいわゆる変数なんだ。ざっくり説明すると、所有権は常に誰か一人が持っていて、所有者(変数)のスコープから外れたら値が削除されるんだ。イメージ的にはリレーのバトン(所有権)を人(変数)が受け渡して処理が進んでいく感じ
1. Rustはね、**Nullの概念は存在しない**のだ。例えば他言語だと、変数の値をdumpしてみて「あ、ここの値NULLなんだ〜」って確認することあるとおもうけど、コンパイルのタイミングでNULLが入る余地がある箇所が見つかったタイミングでエラーになるのよ
1. Rustはね、コンパイルタイミングでめちゃくちゃエラーメッセージでるんだ。でも焦らないで、めちゃくちゃ出る分どこでどういう原因でエラーになったかを親切に押してくれるから。(僕は英語弱々だったから無事頭を抱えました)

参考：https://doc.rust-jp.rs/book-ja/title-page.html

# Rustで遊びながら学んでみる

ここからはあかちゃん置いてけぼりにして、いろいろ試した結果とまとめていきます

環境構築をせずともブラウザ上で色々試せれるのでおすすめです！
https://play.rust-lang.org/

## パターン①

```
fn main() {
    let a = String::from("hoge");
    let b = a;
    println!("{}",a);
    println!("{}",b);
}
error[E0382]: borrow of moved value: `a`
 --> src/main.rs:4:19
```
これはエラーになって
```fn main(){
    let a = "hoge";
    let b = a;
    println!("{}",a);
    println!("{}",b);
}
hoge
hoge
```
これはエラーにならない！！！！なんで！！！！！！

調べたら、
文字列を扱う場合 String,&str2種類あり
ざっくりいうと&strは固定値、Stringは可変値として扱うことができて、値の保持される場所(スタック,ヒープ)違うらしい。
![スクリーンショット 2022-12-11 7.01.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212395/cd2459df-e8f0-f010-3025-8ffa217095e2.png)参考:https://doc.rust-jp.rs/rust-by-example-ja/std/str.html

可変値を所有する変数は自分の役割を終えると値が削除されるので、すでに削除された値の変数を呼ぶとエラーとなる。

逆に下のパターンは、暗黙的に&strの固定値として扱われていて、この場合はデータの保管場所が異なるため削除されずにエラーにならない。

で、borrow of moved valueを解決するのは借用という仕組みを使うことで解決できた
```
    let a = String::from("hoge");
    let b = &a;←上で指定した変数に&をつける
```

## パターン2

```
fn main() {
    let a = "hoge";
    let b = a + "fuga";
    println!("{}",a);
    println!("{}",b);
}
cannot add `&str` to `&str`
```
これはエラーになって
```
fn main() {
    let a = 50;
    let b = a + 100;
    println!("{}",a);
    println!("{}",b);
}
50
150
```
これはエラーにならない！！！！なんで！！！！！

型の扱いが原因で
そもそも、文字の固定値と固定値をそのまま結合できない。
もし行いたい場合、上の公式の説明にもあった **「&strはいつでもStringに変換することができる」** ので、結合先で可変値として扱うように明示しないといけないのでこういう記述にすれば解決された。

```
fn main() {
    let a = "hoge";
    let b = String::new() + a + "fuga";
    println!("{}",a);
    println!("{}",b);
}
hoge
hogefuga
```

ってことで、メモリについてやら型について、いろいろ試したんですが今回はここまで

# まとめ

Rustについてはまだまだ勉強途中なので今後も継続してやっていこうと思います。

メモリ管理やスタックとかヒープあたりの概念に触れたことがなかったので「あれもしらない！待ってこれも知らない！！」が多すぎて、今までなんとなくエンジニアしてた部分をより深く知るきっかけになったので個人的にはよかったです。

とても、導入も簡単だったので何も試したことないよって人は一緒にRustに触れれたらいいなと思います🎸
ではまた〜〜〜〜