Reputation: 113
I understand the reason why this error is being raised, but not sure how I should go about fixing it. Ideally I would want to avoid using Copy
.
fn get_random_samples<'a>(kmers: &[Box<str>], sample_size: usize) -> Vec<Box<str>> {
let mut rng = rand::thread_rng();
kmers
.choose_multiple(&mut rng, sample_size)
.map(|item| *item)
.collect::<Vec<Box<str>>>()
}
This raises the compilation error:
error[E0507]: cannot move out of `*item` which is behind a shared reference
--> src\lib.rs:384:21
|
384 | .map(|item| *item)
| ^^^^^ move occurs because `*item` has type `Box<str>`, which does not implement the `Copy` trait
I've also tried:
fn get_random_samples<'a>(kmers: &[Box<str>], sample_size: usize) -> Vec<Box<str>> {
let mut rng = rand::thread_rng();
kmers
.choose_multiple(&mut rng, sample_size)
.copied()
.collect::<Vec<Box<str>>>()
}
as learned from a previous question (Random sampling of a string slice), but this raises a different error:
error[E0277]: the trait bound `Box<str>: std::marker::Copy` is not satisfied
--> src\lib.rs:384:10
|
384 | .copied()
| ^^^^^^ the trait `std::marker::Copy` is not implemented for `Box<str>`
|
note: required by a bound in `std::iter::Iterator::copied`
--> C:\Users\shant\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib/rustlib/src/rust\library\core\src\iter\traits\iterator.rs:2987:12
|
2987 | T: Copy,
| ^^^^ required by this bound in `std::iter::Iterator::copied`
Both errors seem to point to the Copy
trait which ideally I would like to avoid.
Any help would be appreciated!.
PS: Quite new to Rust, please do suggest if there's better ways to do this.
Upvotes: 2
Views: 2017
Reputation: 42756
If you want to avoid copying/cloning, you need to return a reference. For example:
use rand::prelude::SliceRandom;
fn get_random_samples(kmers: &[Box<str>], sample_size: usize) -> Vec<&Box<str>> {
let mut rng = rand::thread_rng();
kmers
.choose_multiple(&mut rng, sample_size)
.collect()
}
or:
use rand::prelude::SliceRandom;
fn get_random_samples(kmers: &[Box<str>], sample_size: usize) -> Vec<&str> {
let mut rng = rand::thread_rng();
kmers.choose_multiple(&mut rng, sample_size).map(|e| e as &str).collect()
}
Upvotes: 1