Reputation: 183
I am writing a very simple recursive program for finding all prime numbers between two numbers:
use std::cmp::PartialOrd;
use std::ops::{Add, Div, Rem, Sub};
fn _is_prime<T>(n: T, dividend: T, one: T) -> bool
where
T: Copy + Rem<Output = T> + Sub<Output = T> + PartialOrd,
{
if dividend == one {
true
} else {
if n % dividend < one {
false
} else {
_is_prime(n, dividend - one, one)
}
}
}
fn _primes_between<'a, T>(a: T, b: T, one: T, v: &'a mut Vec<T>) -> &'a mut Vec<T>
where
T: Copy + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
if a <= b {
if _is_prime(a, a - one, one) {
v.push(a);
}
_primes_between(a + one, b, one, v)
} else {
v
}
}
fn primes_between<T>(a: T, b: T) -> Vec<T>
where
T: Copy + Div<Output = T> + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
let one = a / a;
let mut v: Vec<T> = Vec::new();
*_primes_between(a, b, one, &mut v)
}
fn main() {
primes_between(3, 13).iter().for_each(|i| println!("{}", i));
}
The problem is:
error[E0507]: cannot move out of a mutable reference
--> src/main.rs:42:5
|
42 | *_primes_between(a, b, one, &mut v)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `std::vec::Vec<T>`, which does not implement the `Copy` trait
How do I solve that error?
Upvotes: 18
Views: 44496
Reputation: 1318
I'm not 100% sure, but I think the problem is that _primes_between()
returns a reference that the code on line 31 is trying to make a copy of. (by taking ownership with the *
operator) You could fix the problem by calling .clone()
on the result, but I think in this case you don't need _primes_between()
to return a value - you can just add the appropriate entries to the v
parameter instead. Something like
fn _primes_between<T>(a: T, b: T, one: T, v: &mut Vec<T>)
where
T: Copy + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
if a <= b {
if _is_prime(a, a - one, one) {
v.push(a);
}
_primes_between(a + one, b, one, v);
}
}
fn primes_between<T>(a: T, b: T) -> Vec<T>
where
T: Copy + Div<Output = T> + Rem<Output = T> + Add<Output = T> + Sub<Output = T> + PartialOrd,
{
let one = a / a;
let mut v: Vec<T> = Vec::new();
_primes_between(a, b, one, &mut v);
v
}
Upvotes: 9