Reputation: 67
When using below function:
fn factors(number: &BigInt) -> Vec<BigInt> {
let mut n = number.clone();
let mut i: BigInt = ToBigInt::to_bigint(&2).unwrap();
let mut factors = Vec::<BigInt>::new();
while i * i <= n {
if (n % i) == ToBigInt::to_bigint(&1).unwrap() {
i = i + ToBigInt::to_bigint(&1).unwrap();
}
else {
n = n/i as BigInt;
factors.push(i);
}
i = i + ToBigInt::to_bigint(&1).unwrap();
}
if n > i {
factors.push(n);
}
factors
}
I get moved value errors for literally every time i
or n
is used, starting from the line with while
, also in the if
. I have read about borrowing, which I understand decently, but this thing I don't understand.
I am not "copying" the value at all, so I don't see anywhere were I could lose ownership of the variables.
Upvotes: 6
Views: 6760
Reputation: 11187
Mul
(and the other arithmetic operators) take the parameters by value, so i * i
move the value i
(this is not a problem for primitive numbers because they implement Copy
- BigInt
does not).
As Mul
is implemented for (two) &BigInt
, you can do the multiplication (and the other arithmetic operations) with &
:
use num::*;
fn factors(number: &BigInt) -> Vec<BigInt> {
let mut n = number.clone();
let mut i = BigInt::from(2);
let mut factors = Vec::new();
while &i * &i <= n {
if (&n % &i) == BigInt::one() {
i = i + BigInt::one();
} else {
n = n / &i;
factors.push(i.clone());
}
i = i + BigInt::one();
}
if n > i {
factors.push(n);
}
factors
}
Note that I also made some simplifications, like omitting the type on Vec::new
and using BigInt::from
(cannot fail).
Upvotes: 9
Reputation: 1316
Remember that operators in Rust are just syntactic sugar for function calls.
a + b
translates to a.add(b)
.
Primitive types such as i32
implement the trait Copy
. Thus, they can be copied into such an add function and do not need to be moved.
I assume the BigInt
type you are working with does not implement this trait.
Therefore, in every binary operation you are moving the values.
Upvotes: 4