這與my earlier question有關使得模冪泛型方法成爲可能。現在我已經來到了下面的代碼:爲什麼二元運算符的這個結果需要適當的生命週期?
fn powm<T>(fbase: &T, exponent: &T, modulus: &T) -> T
where
T: Mul<T, Output = T>
+ From<u8>
+ PartialEq<T>
+ Rem<T, Output = T>
+ Copy
+ for<'a> Rem<&'a T, Output = T>
+ Clone
+ PartialOrd<T>
+ ShrAssign<T>,
for<'a> &'a T: PartialEq<T> + Rem<&'a T, Output = T>,
{
if modulus == T::from(1) {
T::from(0)
} else {
let mut result = T::from(1);
let mut base = fbase % modulus;
let mut exp = exponent.clone();
while exp > T::from(0) {
if exp % T::from(2) == T::from(1) {
result = (result * base) % modulus;
}
exp >>= T::from(1);
base = (base * base) % modulus;
}
result
}
}
這是我的理解是通過定義特徵約束where for<'a> &'a T: Rem<&'a T, Output=T>
是可以理解的,我可以用模運算%
上&'a T
類型的兩個操作數,然後將結果將是類型T
。不過,我得到以下錯誤:
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/main.rs:20:30
|
20 | let mut base = fbase % modulus;
| ^
|
note: first, the lifetime cannot outlive the anonymous lifetime #3 defined on the function body at 3:1...
--> src/main.rs:3:1
|
3 |/fn powm<T>(fbase: &T, exponent: &T, modulus: &T) -> T
4 | | where
5 | | T: Mul<T, Output = T>
6 | | + From<u8>
... |
30 | | }
31 | | }
| |_^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:20:32
|
20 | let mut base = fbase % modulus;
| ^^^^^^^
note: but, the lifetime must be valid for the anonymous lifetime #1 defined on the function body at 3:1...
--> src/main.rs:3:1
|
3 |/fn powm<T>(fbase: &T, exponent: &T, modulus: &T) -> T
4 | | where
5 | | T: Mul<T, Output = T>
6 | | + From<u8>
... |
30 | | }
31 | | }
| |_^
note: ...so that types are compatible (expected std::ops::Rem, found std::ops::Rem<&T>)
--> src/main.rs:20:30
|
20 | let mut base = fbase % modulus;
| ^
如果我通過
let mut base = fbase.clone() % modulus;
更換有問題的代碼行的代碼不工作,我不明白爲什麼我需要擺在首位,如果克隆我可以使用模運算符來返回類型爲T
的「新鮮」元素。我需要修改我的特質範圍嗎?爲什麼這會出錯?
FWIW,我可能只是[避免參考](https://play.integer32.com/?gist=9889ac1244f40e9bb180c6292895401c&version=stable)。 – Shepmaster