2017-03-22 4 views
1

Vecをパラメータとするmax関数を書きました。私の期待通りに機能します。1つのVecをRustの複数の関数に渡すには?

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); 
} 

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 
} 

錆は私がminへの呼び出しに同じmy_arrayパラメータを置く場合はエラーを報告します:

私はコードを書くことができますどのように
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 the `Copy` trait 

それから私は、max関数と同じminの機能を追加しました作品ですか?

+4

[移動セマンティクス](https://doc.rust-lang.org/stable/book/ownership.html#move-semantics)についてお読みください。 –

答えて

10

これは非常に初心者のRustが経験する問題です。初心者の方はThe Rust Programming Languageとお読みください。この本には多くの努力が払われています。特に、Rustの新入社員のためです。これはあなたが走る多くのことをカバーします。

関連セクション:


根本的な問題は、あなたが呼び出すベクトルの転送所有権をしたということですmax。値は次に消えます。 mainはもう持っていません。

maxに渡す前にベクターをクローンするのが最も簡単です。これはmainmy_arrayの所有権を維持し、その後、後続の行にminに所有権を譲渡することができます:

let max = max(my_array.clone()); 
let min = min(my_array); 

maxminどちらが自分の仕事をするために、ベクターの所有権を取得する必要があるとして、これは、非効率的です。 Vecのクローニングには、さらにメモリを割り当てる必要があります。それはVec内のデータへの参照の種類であるスライス、渡すために多くの慣用的です:

let max = max(&my_array); 
let min = min(&my_array); 

// ... 

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

スライスを反復すると、あなたはスライス内の項目への参照を取り戻します。整数では、それらを逆参照することができます(ここでは&for &val in arrayにしています)、値のコピーを作成します。


さらに、このような基本機能を書き換える必要はありません。 には、少なくとも1つの値があると仮定します。これは空のベクトルには当てはまりません。慣用的な解決策は、iteratorsを使用することである。

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

これは空のスライスがない最小値または最大値を持たないように、それぞれが、Optionを返すIterator::minIterator::max、 を使用します。

minmaxOption<&i32>あるとして技術的には、それは、あなたの元の溶液から少し違うのです。元のスライスへの参照です。

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

ボーナス情報:あなたはOption::clonedを使用してOption<i32>に戻って取得することができ、スライス、Vec Sを、配列はすべての異なる種類があります。配列としてmy_arrayを参照するのは正しくありません。

関連する問題