Rust基本文法①

#この記事の目的
[参考サイト](https://doc.rust-jp.rs/rust-by-example-ja/primitives.html)を参考にRustの基本的文法の確認。
CやC++に比べていい点を抽出。

#良いと思った点
・Rustには型推論があるため、明示的に型を書かなくてもどこかで確定する箇所があれば問題ない。
　使用箇所がなく型が確定しない場合はビルドエラーになる。
・初期化していない変数の利用はビルドエラー
・暗黙的な型変換はビルドエラー
・基本的なミスはビルドエラーで防げる点

#Print

```rust:qiita.rs
#[derive(Debug)]

struct Person<'a> {
    name: &'a str,
    age: u8
}

fn main() {
    let a=5i32;//値：型指定
    println!("{}",a);//5
    println!("{}",31);//31
    println!("{0}, this is {1}. {1}, this is {0}", "Alice", "Bob");//引数の一から埋め込まれる場所を指定可能
    println!("{subject} {verb} {object}",
    object="the lazy dog",
    subject="the quick brown fox",
    verb="jumps over");//変数名で指定できる

    println!("{number:>width$}", number=1, width=6);//widthでスペースの数を指定

    let name = "Peter";
    let age = 27;
    let peter = Person { name, age };
    println!("{:#?}", peter);//構造体での表示

}

```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/680528/84e21f94-3f64-2995-f41f-2e70a9a8dbeb.png)


#演算
```rust:qiita.rs
fn main() {

    println!("1+2={}",1u32+2);
    println!("1+2={}",1i32+2);
    //println!("1-2={}",1u32-2);//`1_u32 - 2_u32`, which would overflowでコンパイルエラー
    println!("1-2={}",1i32-2);

    println!("4/2={}",4/2);
    println!("4*2={}",4*2);
    println!("2^2={}",2<<2);

    println!("0011 && 0001={}",0b0011 & 0b0001);
}


```

#配列
範囲外アクセスはコンパイル時にエラーにならない...

```rust:qiita.rs
use std::mem;
fn main() {

    //tuple
    let tuple =(1,"Hello",true);
    let (a,b,c)=tuple;
    println!("{},{},{}",a,b,c);

    //配列　[T;サイズ]
    let array: [i32; 5] = [1, 2, 3, 4, 5];
    for i in 1..5//1~5まで
    {
        println!("{}",array[i]);
    }

    // for i in 1..6//1~5まで
    // {
    //     //範囲外アクセスになるコードでもコンパイルエラーは出ない。
    //     println!("{}",array[i]);
    // }

    println!("length:{},bytes:{}",array.len(),mem::size_of_val(&array));
}
```

#構造体
```rust:qiita.rs
fn main() {

    //tuple struct
    struct Pair(i32,f32);
    let pair=Pair(1,0.1);
    println!("{},{}", pair.0, pair.1);

    //C style
    struct Point{
        x:i32,
        y:i32,
    }
    let point=Point(1,2);
    println!("{},{}", point.x, point.1);//要素アクセスもインデックスアクセスでもOK

    //struct Unit
    struct Unit;
}

```

#enum
変数をもらったり、構造体をメンバとして持つこともできる。

```rust:qiita.rs
enum WebEvent {
    // An `enum` may either be `unit-like`,
    PageLoad,
    PageUnload,
    // like tuple structs,
    KeyPress(char),//（変数名）方が分かる名前のほうがよさそう
    Paste(String),
    // or c-like structures.
    Click { x: i64, y: i64 },
}

// A function which takes a `WebEvent` enum as an argument and
// returns nothing.
fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("page loaded"),
        WebEvent::PageUnload => println!("page unloaded"),
        // Destructure `c` from inside the `enum`.
        WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
        WebEvent::Paste(s) => println!("pasted \"{}\".", s),
        // Destructure `Click` into `x` and `y`.
        WebEvent::Click { x, y } => {
            println!("clicked at x={}, y={}.", x, y);
        },
    }
}

//C style
enum Color
{
    Red=0,
    Green,
    Blue,
}

fn main() {
    let pressed = WebEvent::KeyPress('x');
    // `to_owned()` creates an owned `String` from a string slice.
    let pasted  = WebEvent::Paste("my text".to_owned());
    let click   = WebEvent::Click { x: 20, y: 80 };
    let load    = WebEvent::PageLoad;
    let unload  = WebEvent::PageUnload;

    inspect(pressed);
    inspect(pasted);
    inspect(click);
    inspect(load);
    inspect(unload);
}
```

#変数バインディング

よい：Rustには型推論があるため、明示的に型を書かなくてもどこかで確定する箇所があれば問題ない。
　　　サフィックスにより宣言時に確定させることも可能。宣言時に確定していないものも使用箇所により自動的に型が確定
　　　使用箇所がなく型が確定しない場合はコンパイルエラーになる。

```rust:qiita.rs
fn main() {
    // Because of the annotation, the compiler knows that `elem` has type u8.
    // アノテーションのおかげで、コンパイラは`elem`がu8型であることがわかる。
    let elem = 5u8;

    // Create an empty vector (a growable array).
    // 空のベクトル（可変長の配列）を生成
    let mut vec = Vec::new();
    // At this point the compiler doesn't know the exact type of `vec`, it
    // just knows that it's a vector of something (`Vec<_>`).
    // この時点でコンパイラは`vec`の型を知らず、
    // 単に何らかの値のベクトル(`Vec<_>`)であるということだけを把握している。

    //型が確定しなくなるのでエラーになる
    //vec.push(elem);
    println!("{:?}", vec);
}


```

よい：変数はデフォルトはconst。書き換え可能な変数にはmutをつける。mut変数もスコープ内でFreeze(値固定）されていれば変更不能となる。


```rust:qiita.rs
fn main() {
    let _immutable = 1;
    let mut mutable = 1;

    println!("Before mutation: {}", mutable);

    // Ok
    mutable += 1;

    println!("After mutation: {}", mutable);

    // Error!
    //_immutable_binding += 1;

   {
     let imutable=mutable;
     // Error!
     //mut変数もスコープ内でconstに指定されていれば変更できない。
     imutable+=1;
   }
}

```

よい：初期化していない変数の利用はビルドエラー

```rust:qiita.rs
fn main() {

    let another_binding;

    // Error! Use of uninitialized binding
    // エラー！ 初期化していない変数の使用
    println!("another binding: {}", another_binding);

    another_binding = 1;

    println!("another binding: {}", another_binding);
}


```

#Types
よい：暗黙的な型変換はコンパイルエラー
明示的な変換には変数名 as 型。

```rust:qiita.rs
fn main() {
  let decimal = 3.3f32;

  // Error! No implicit conversion
  // エラー！ 暗黙的な型変換はできない。
  let integer: u8 = decimal;

  // Explicit conversion
  // 明示的な型変換
  let integer = decimal as u8;
  let character = integer as char;
}

```
C++では暗黙的な型変換により情報落ちが発生する可能性がある。

```c++:qiita.cpp
void main() {

	float a = 3.3;
	cout << a << endl;//3.3

	auto b = a;

	int c = b;
	cout << c << endl;//3

}

```