---
# System prepended metadata

title: Rust演習

---

# Rust演習

## プロジェクト作成

プロジェクト作成
```bash
cargo new myproj
cd myproj
```

ビルド
```bash
cargo build
```

実行
```bash
cargo run
# hello world
```



## 変数と可変性

`let var`で定義した変数varは変更することができない。`let mut var`

```rust
//コンパイルエラー

fn main() {
    let x = 5;
    println!("The value of x is: {}", x);
    x = 6;    //xは変更できない
    println!("The value of x is: {}", x);
}
```
上のコードはエラーが出るので、以下のように書き換える必要がある。
```rust
fn main() {
    let mut x = 5;
    println!("The value of x is: {}", x);
    x = 6;    //xは変更できない
    println!("The value of x is: {}", x);
}
```

### 戻り値の書き方
```rust
fn main() {
    println!("{}",add1(100,200));
    println!("{}",add2(150,250));
}

fn add1(x:i32, y:i32) -> i32{
    let ans = x + y;
    return ans;
}

fn add2(x:i32,y:i32)  -> i32{
    let ans = x + y;
    ans
}
```

## 所有権

### 変数のスコープ

```rust
//コンパイルエラー

fn main() {
    {
        let x = 5;
        let s = String::from("hello");
    }
    println!("{}",x);
    println!("{}",s);
}
```
変数s(が指し示すデータ)は中括弧の中のみで有効なので、以下のように書き換える。
```rust
fn main() {
    {
        let x = 5;
        let s = String::from("hello");
        println!("{}",x);
        println!("{}",s);
    }
}
```

### 変数の束縛と所有権の移動

```rust
fn main(){
    let x = 5;
    let y = x;
    println!("{}",x);
}
```

```rust
//コンパイルエラー

fn main(){
    let s1 = String::from("hello");
    let s2 = s1;//"hello"の所有権がs1からs2に移動
    println!("{}",s1);
}
```

### 関数とスコープ

```rust
//コンパイルエラー

fn main() {
    let s1 = String::from("hello");
    let len1 = calculate_length(s1);
    let len2 = calculate_length(s1);
}

fn calculate_length(s: String) -> usize {
    let length = s.len(); // len()メソッドは、Stringの長さを返します
    length
}
```

### 一つの解決法(所有権を、戻り値で渡してもどす。)
```rust
fn main() {
    let s1 = String::from("hello");

    let (s2, len) = calculate_length(s1);

    //'{}'の長さは、{}です
    println!("The length of '{}' is {}.", s2, len);
}

fn calculate_length(s: String) -> (String, usize) {
    let length = s.len(); // len()メソッドは、Stringの長さを返します

    (s, length)
}
```

面倒なので、所有権を移動させないままでヒープデータを扱いたい。

## 参照
```rust
fn main() {
    let s1 = String::from("hello");
    let len1 = calculate_length(&s1);
    let len2 = calculate_length(&s1);
}

fn calculate_length(s: &String) -> usize {
    let length = s.len(); // len()メソッドは、Stringの長さを返します
    length
}
```
