2016-06-14 28 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類型沒有實現這個特性。 因此,在每個二進制操作中,您都在移動這些值。