Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
5
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

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

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)の理解には役立ったので、覚え書きとして記述&投稿した。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
5
Help us understand the problem. What are the problem?