LoginSignup
10
6

More than 5 years have passed since last update.

Rustの所有権(Ownership)について

Last updated at Posted at 2017-03-22

Rustの所有権(Ownership)について良く理解できないままドキュメントの説明を読んでいたが、自分でサンプルコードを記述しているうちに、理解する必要が出てきた。

まず、よくありがちな配列(Vectors)を使用して、Max関数に引数を渡す例。

max_main.rs
fn main() {
    let my_array = vec![61,14,71,23,42,8,13,66];
    let max = max(my_array);
    println!("Max value is {}.", max);
    // => Max value is 71.
}

fn max(array: Vec<i32>) -> i32{
    let mut max = array[0];
    for val in array{
        if max < val {
            max = val;
        }
    }
    max
}

思った通りに動作する。

その後、Min関数を作成する。そして同様の配列の変数を渡す。

max_main.rs
fn main() {
    let my_array = vec![61,14,71,23,42,8,13,66];
    let max = max(my_array);
    let min = min(my_array);
    println!("Max value is {}.", max);
    println!("Min value is {}.", min);
}

fn max(array: Vec<i32>) -> i32{
    let mut max = array[0];
    for val in array{
        if max < val {
            max = val;
        }
    }
    max
}

fn min(array: Vec<i32>) -> i32{
    let mut min = array[0];
    for val in array{
        if min > val {
            min = val;
        }
    }
    min
}

残念ながらエラーとなる。

error[E0382]: use of moved value: `my_array`
 --> src/main.rs:4:19
  |
3 |     let max = max(my_array);
  |                   -------- value moved here
4 |     let min = min(my_array);
  |                   ^^^^^^^^ value used here after move
  |
  = note: move occurs because `my_array` has type `std::vec::Vec<i32>`, which does not implement t
he `Copy` trait

理由は、Rustの独自仕様である所有権(Ownership)の問題。
問題というより、他言語に馴染んでいるとハマる部分。
一度でも、プリミティブでない変数への参照が使用されると、参照可能な所有権が移ってしまい、その後に参照しようとするとエラーとなる。

この場合、下記のように修正する必要がある。

max_main.rs
fn main() {
    let my_array = vec![61,14,71,23,42,8,13,66];
    let max = max(&my_array);
    let min = min(&my_array);
    println!("Max value is {}.", max);
    println!("Min value is {}.", min);
    // => Max value is 71.
    // => Min value is 8.
}

fn max(array: &[i32]) -> i32{
    let mut max = array[0];
    for &val in array{
        if max < val {
            max = val;
        }
    }
    max
}

fn min(array: &[i32]) -> i32{
    let mut min = array[0];
    for &val in array{
        if min > val {
            min = val;
        }
    }
    min
}

まだまだRust勉強中であり、このメリットは感じられないが、まずは所有権(Ownership)の理解には役立ったので、覚え書きとして記述&投稿した。

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6