我想实现一个通用的 fibonacci
适用于实现 Zero
的任何类型的函数, One
, 和 AddAssign
.我首先实现了一个工作正常的版本,但专门用于 num::BigUint
(see on play.rust-lang.org)。我想出了以下通用实现 ( see on play.rust-lang.org ):
extern crate num;
use num::{One, Zero};
use std::mem::swap;
use std::ops::AddAssign;
fn fib<T: Zero + One + AddAssign<&T>>(n: usize) -> T {
let mut f0 = Zero::zero();
let mut f1 = One::one();
for _ in 0..n {
f0 += &f1;
swap(&mut f0, &mut f1);
}
f0
}
这不编译:
error[E0106]: missing lifetime specifier
--> src/main.rs:7:34
|
7 | fn fib<T: Zero + One + AddAssign<&T>>(n: usize) -> T {
| ^ expected lifetime parameter
Rust 要我给 AddAssign<&T>
添加一个生命周期参数但我不知道如何表达 f1
的生命周期.
最佳答案
您需要使用 Higher Rank Trait Bounds .这基本上意味着“对于任何生命周期 'a
, T
满足 AddAssign<&'a T>
特征”:
fn fib<T>(n: usize) -> T
where
for<'a> T: Zero + One + AddAssign<&'a T>,
我也不得不改变方式fib
被调用是因为编译器无法计算出返回类型,它实际上可以是实现这些特征的任何类型。声明 x
的类型为编译器提供了足够的上下文,以便它知道您想要什么。
fn main() {
let x: num::BigUint = fib(10);
// let x = fib::<BigUint>(10); // Also works
println!("fib(10) = {}", x);
}
关于generics - 如果我在函数内部创建引用,如何将泛型类型与需要生命周期参数的特征绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47996700/