2016-06-14 46 views
0

的使用以下功能:锈使用移动值

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 
} 

我得到移动值误差字面上每次为in时,从开头的行while,也在if。我读过关于借款的文章,我理解得体,但这个东西我不明白。 我根本不是“复制”这个值,所以我没有看到任何地方我可能会失去变量的所有权。

+1

BigInt是什么类型?它来自哪个箱子? –

+0

ow,对不起,它来自'num'。这是一个很大的int,它没有实现'Copy'特性,因为这会非常非常非常耗费CPU时间。 (我知道我也在这里复制,我无法找到更好的解决方案) – Epse

+0

啊不需要道歉,只是想知道他们是哪种类型。 –

回答

6

Mul(和其他算术运算符)的值的参数时,所以i * i移动值i(因为它们实现Copy这不是原始的数字的问题 - BigInt没有)。

至于Mul为(二)&BigInt实现,你可以用&做乘法(和其他算术运算):

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 
} 

请注意,我也做了一些简化,像Vec::new省略类型并使用BigInt::from(不能失败)。

+0

这是有道理的。什么是BigInt :: one()包含在里面,因为某些原因,Rust无法找到它......编辑:发现它,它拼写一个大写,包括它出于任何原因 – Epse

+1

你必须导入['num: :One'](http://rust-num.github.io/num/num/trait.One.html) – malbarbo

+2

@Epse'num :: One'是一个特质,所以是大写。特征包括一个函数,“One :: one”,如果特征也是可见的,那么这个特征只能用于特征实现者。 – Veedrac

2

请记住,Rust中的运算符只是函数调用的语法糖。

a + b转换为a.add(b)

原始类型,例如i32执行特征Copy。因此,它们可以被复制到这样一个添加功能中,而不需要移动。

我假设你正在使用的BigInt类型没有实现这个特性。 因此,在每个二进制操作中,您都在移动这些值。