RustとRubyの違い

# RustとRubyの違い
---
# Mut
---
- Ruby: 変数は値変えられます

```ruby
hoge = 1
hoge = 2
p hoge

# 結果: => 2
```

---
- Rust: 変数は値変更不可(`immutable`)

```rust
fn main() {
  let hoge = 1;
  hoge = 2;
  
  <!-- 
    ビルドエラー 
    error[E0384]: cannot assign twice to immutable variable `hoge` 
  -->
  
  
  println!("Hoge {:}", hoge);
}

```

---

- Rust: 変数の値変更したい場合、`mut`を付けないといけません

```rust
fn main() {
  let mut hoge = 1;
  hoge = 2;
  
  println!("Hoge {:}", hoge);
  <!-- 結果: Hoge 2 -->
}
```
---

# 型
---
- Ruby: 変数の型がありません、コンパイラーは値から型を付けます (PHPなどと同じ)

```ruby
hoge = "as"
a.class
# => String

hoge = 12
hoge.class
# => Integer
```
---

- Rust: 変数の型は変更出来ません、(C, Java, Cotlin, Swiftなどと同じ)

```rust
fn main() {
  let mut hoge = 1; 
  <!-- Hoge変数は `&str` 型になります-->

  hoge = "hola";
  // ビルドエラー 
  // error[E0308]: mismatched types
  //  |
  //  |     hoge = "hola";
  //  |            ^^^^^^ expected integer, found `&str`
  
  println!("Hoge {:}", hoge);
}

```
---

# 変数のReference
---
- Rustはreferenceがあります。(Cと同じ)

```rust
fn main() {

  let a: u8 = 10;
  let b = &a;
  println!("Pointer a: {:p}", b);
  println!("Value   a: {}", a);
  println!("Value   b: {}", b);
}
  
  // Pointer a: 0x7ffd469b821f
  // Value   a: 10
  // Value   b: 10
}
```
---

- Ruby: 全部はobjectなので、変数はPointerです。Rustの書き方が存在しません

```ruby
a = 12
b = &a

# コンパイラーエラー
# SyntaxError ((irb):23: syntax error, unexpected &)
```

---
- RubyのReference

```ruby
class Hoge attr_accessor :name end
hoge = Hoge.new
fuga = hoge

hoge.name = "hoge"
p fuga.name
# 結果
# => "hoge"

fuga.name = "fuga"
p hoge.name
# 結果
# => "fuga"

```
---

## 質問1

```rust
fn main() {

  let mut a: u8 = 10;
  let b = &mut a;
  
  a = 11;
  println!("Value a: {:}", a);
}
```
→　エラーがありますか？

---

## 質問1の答え
- エラーはありません

---
## 質問2
```rust
fn main() {

  let mut a: u8 = 10;
  let b = &mut a;
  
  a = 11;
  println!("Value b: {:}", b);
}
```
→　結果はどうなりますか？

---
## 質問2の答え
- エラー発生します

```rust
 --> src/main.rs:7:3
  |
7 |   a = 11;
  |   ^
  |
  = note: `#[warn(unused_assignments)]` on by default
  = help: maybe it is overwritten before being read?

error[E0506]: cannot assign to `a` because it is borrowed
 --> src/main.rs:7:3
  |
5 |   let b = &mut a;
  |           ------ borrow of `a` occurs here
6 |   
7 |   a = 11;
  |   ^^^^^^ assignment to borrowed `a` occurs here
8 |   println!("Value b: {:}", b);
  |                            - borrow later used here

error: aborting due to previous error; 1 warning emitted

```

---
# Borrowing と Ownership
---

- Rubyでオーナーとういう概念がない、複数変数はひとつのデータに参照するときに、どの変数でもデータ変更できます

```ruby
class Hoge attr_accessor :name end
hoge = Hoge.new
fuga = hoge

hoge.name = "hoge"
p fuga.name
# 結果
# => "hoge"

fuga.name = "fuga"
p hoge.name
# 結果
# => "fuga"

```
---

- Rust: 一つの変数だけデータ変更できます。

```rust
struct Hoge {
    count: i32,
}
fn main() {
    let mut hoge = Hoge {count: 1};
    let fuga = &mut hoge;
    fuga.count = 2;
    println!("Hoge count: {:}", hoge.count);
    hoge.count = 3;
    println!("Hoge count: {:}", fuga.count);

    //     error[E0502]: cannot borrow `hoge.count` as immutable because it is also borrowed as mutable
    //   --> src/main.rs:8:33
    //    |
    // 6  |     let fuga = &mut hoge;
    //    |                --------- mutable borrow occurs here
    // 7  |     fuga.count = 2;
    // 8  |     println!("Hoge count: {:}", hoge.count);
    //    |                                 ^^^^^^^^^^ immutable borrow occurs here
    // 9  |     hoge.count = 3;
    // 10 |     println!("Hoge count: {:}", fuga.count);
    //    |                                 ---------- mutable borrow later used here

    // error[E0506]: cannot assign to `hoge.count` because it is borrowed
    //   --> src/main.rs:9:5
    //    |
    // 6  |     let fuga = &mut hoge;
    //    |                --------- borrow of `hoge.count` occurs here
    // ...
    // 9  |     hoge.count = 3;
    //    |     ^^^^^^^^^^^^^^ assignment to borrowed `hoge.count` occurs here
    // 10 |     println!("Hoge count: {:}", fuga.count);
    //    |                                 ---------- borrow later used here
}

```
---

# Nil vs Option
---
- Ruby: どの変数でもnil付けられます

```ruby
  x = 2;
  y = nil;
    
  print "x: #{x}, y: #{y}"
  # 結果
  # x: 2, y: => nil
```
---

- Rust: nilは存在しません　→　代わりにデータがある・ないの型があります　→　Option

```rust

fn main() {
    let x: Option<u32> = Some(2);
    let y: Option<u32> = None;
    
    println!("x: {:?}, y: {:?}", x, y)
}

```
---

- Rust OptionのNone = Rubyのnil
- RUst OptionのSome = RUbyのnilじゃない

---
- Ruby: Nilに関連するoperatorがありません

```ruby
a = nil
b = a + 1
# NoMethodError (undefined method `+' for nil:NilClass)
```
---
- Rust: Optionに関連するoperatorもありません、ただOptionのデータで使うとときに、Noneをチェックしないといけません　→　安全です

```rust
fn main() {
  let a: Option<u32> = Some(2);

  let value = match a {
    Some(v) => v,
    None => 0 
  };

  let b = value + 1;
  
  println!("b: {:}", b);
}
```
---

# Result - エラーハンドリング
---
- エラーは外部APIまたは特別な処理の時に、エラー発生します。

例：　FbApiError, ValidationError..

---
- Ruby: 関数開発の時にエラー気にしなくも開発出来ます

```ruby

def call_api(endpoint, method)
   fb_client.call(endpoint, method) # エラーがある処理
   
   'API Done'
end

```
---

- Ruby: エラーハンドリングの時に開発者に決められます。

```ruby

def call_api(endpoint, method)
  begin
    fb_client.call(endpoint, method)
  rescue => exception
    'API ERROR'
  end

  'API Done'
end

```
---

- Ruby: エラーハンドリングしないと関数が呼ばれるところにエラー投げます。

```ruby
def call_api(endpoint, method)
   fb_client.call(endpoint, method) # エラーがある処理
   
   'API Done'
end

call_api("me", "GET") # fb_client.call でエラー発生したら、ここに止まります。
```
---

- Rust:  関数開発の時にエラーがあれば、Resultとうい型になります。

```rust
    pub async fn call_api(&self, endpoint: &str, method: &str) -> String{
        self.call(endpoint, method) // エラーがある処理

        "API DONE".to_owned()
    }
```
---

- Rust: Resultをみるとエラーがあるかどうか分かります。

```rust
    pub async fn call_api(&self, endpoint: &str, method: &str) -> String{
        return match self.call(endpoint, method) {
             Ok(value) => "API DONE".to_owned(),
             Err(error) => "API ERROR".to_owned()
        }
    }

```
---

- Rust: エラーハンドリングしないときに、エラー発生したら何も起こらない


```rust
    pub async fn call_api(&self, endpoint: &str, method: &str) -> String{
        await self.call(endpoint, method) // エラーがある処理

        "API DONE".to_owned()
    }

    pub async fn run(&self){
        await self.call_api("me", "GET") // .call でエラー発生しても、何も起こらない
    }

```

# まとめ
- Mut
- 型
- Reference
- Nil/Option
- Result