patternrustCritical
What is the idiomatic Rust way to copy/clone a vector in a parameterized function?
Viewed 0 times
idiomaticfunctionclonethecopyvectorwayrustwhatparameterized
Problem
I'm trying to write a parameterized function that takes an immutable vector, clones or copies it, does something to the new vector (such as shuffle it) and returns it as a new owned vector. How can this be done and what is the most idiomatic way to do it?
Attempt #1
Fails with:
even though I declared
Attempt #2
While this compiles, it doesn't do what I want. The vector you pass into
I want to know how to pass in a vector that will not be mutated, but have the values cloned into a new boxed vector and returned when finished - as you do in a functional programming language that has immutable data (such as Clojure).
Attempt #1
pub fn shuffle(vec: &mut [T]) {
// ... contents removed: it shuffles the vector in place
// ... so needs a mutable vector
}
pub fn shuffle_create_new(vec: &[T]) -> Vec {
let mut newvec = vec.clone();
shuffle(&mut newvec);
return newvec.to_owned();
}Fails with:
error[E0596]: cannot borrow immutable borrowed content as mutable
--> src/main.rs:8:13
|
8 | shuffle(&mut newvec);
| ^^^^^^^^^^^ cannot borrow as mutable
even though I declared
newvec as mutable. I don't understand why.Attempt #2
pub fn shuffle_owned(mut vec: Vec) -> Vec {
shuffle(&mut vec);
return vec;
}While this compiles, it doesn't do what I want. The vector you pass into
shuffle_owned gets moved into the function, shuffled and then has its ownership transferred back to the caller (via the return value). So the original vector is modified.I want to know how to pass in a vector that will not be mutated, but have the values cloned into a new boxed vector and returned when finished - as you do in a functional programming language that has immutable data (such as Clojure).
Solution
Your attempt #1 is almost correct, you just have to move
This happens because calling
As of Rust 1.0, either
There are also now several ways to obtain
to_owned() to the first line:fn shuffle(vec: &mut [T]) {
// ...
}
fn shuffle_create_new(vec: &[T]) -> Vec {
let mut newvec = vec.to_vec();
shuffle(&mut newvec);
newvec
}This happens because calling
clone() on a slice will return you a slice (i.e. &[T]), and you cannot go from &[T] to &mut [T] because you cannot choose mutability of a reference (borrowed pointer). When you call to_owned(), however, you are getting a fresh instance of Vec and you can put it into a mutable variable to get mutable vector.As of Rust 1.0, either
slice::to_vec or to_owned() method from the ToOwned trait can be used to create Vec from &[T].There are also now several ways to obtain
&mut [T] from Vec: the slicing notation (&mut vec[..]), the deref conversion (&mut *vec) or the direct method call (vec.as_mut_slice(), though this one is deprecated):Code Snippets
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
}Context
Stack Overflow Q#21369876, score: 104
Revisions (0)
No revisions yet.