不変のベクターを受け取り、それを複製またはコピーし、新しいベクターに何らかの処理を行い(シャッフルするなど)、新しい所有ベクターとして返すパラメーター化された関数を作成しようとしています。どのようにこれを行うことができ、それを行うための最も慣用的な方法は何ですか?
試行#1
pub fn shuffle<T>(vec: &mut [T]) {
// ... contents removed: it shuffles the vector in place
// ... so needs a mutable vector
}
pub fn shuffle_create_new<T: Clone>(vec: &[T]) -> Vec<T> {
let mut newvec = vec.clone();
shuffle(&mut newvec);
return newvec.to_owned();
}
失敗する:
error[E0596]: cannot borrow immutable borrowed content as mutable
--> src/main.rs:8:13
|
8 | shuffle(&mut newvec);
| ^^^^^^^^^^^ cannot borrow as mutable
newvec
を可変と宣言しましたが。理由がわかりません。
試行#2
pub fn shuffle_owned<T: Clone>(mut vec: Vec<T>) -> Vec<T> {
shuffle(&mut vec);
return vec;
}
これはコンパイルしますが、私が望むことはしません。渡すベクトルshuffle_owned
は、関数にmovedを取得し、シャッフルし、所有者を呼び出し側に(戻り値を介して)転送します。したがって、元のベクトルはmodifiedです。
notが変更されるベクトルを渡す方法を知りたいが、値が新しいボックス化されたベクトルに複製され、終了時に返される-不変データを含む関数型プログラミング言語で行うように(Clojureなど)。
あなたの試み#1はほぼ正しいです。あなたはto_owned()
を最初の行に移動するだけです:
fn shuffle<T>(vec: &mut [T]) {
// ...
}
fn shuffle_create_new<T: Clone>(vec: &[T]) -> Vec<T> {
let mut newvec = vec.to_vec();
shuffle(&mut newvec);
newvec
}
これは、スライスでclone()
を呼び出すとスライス(つまり&[T]
)が返され、&[T]
から&mut [T]
に変更できないためです。参照(借用ポインター)。ただし、to_owned()
を呼び出すと、Vec<T>
の新しいインスタンスを取得し、それを可変変数に入れて可変ベクトルを取得できます。
Rust 1.0、 slice::to_vec
またはToOwned
の- to_owned()
メソッドのいずれかtraitを使用して、Vec<T>
から&[T]
を作成できます。
&mut [T]
からVec<T>
を取得する方法もいくつかあります。スライス表記(&mut vec[..]
)、deref変換(&mut *vec
)、または直接メソッド呼び出し(vec.as_mut_slice()
、これは非推奨ですが)
これはおそらくあなたが望むものです:
pub fn copy_shuffle<T: Clone>(vec: &Vec<T>) -> Vec<T> {
let mut vec = vec.clone();
shuffle(&mut vec);
vec
}
または
pub fn copy_shuffle<T: Clone>(vec: &[T]) -> Vec<T> {
let mut vec = vec.to_vec();
shuffle(&mut vec);
vec
}