如果我在函数内部创建引用,如何将泛型类型与需要生命周期参数的特征绑定?

lov*_*soa 5 generics lifetime rust

我想实现一个通用的fibonacci,与任何类型的工作实现的功能Zero,One以及AddAssign.我首先实现了一个工作正常的版本,但是专门用于num::BigUint(参见play.rust-lang.org).我想出了以下通用实现(参见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
}
Run Code Online (Sandbox Code Playgroud)

这不编译:

error[E0106]: missing lifetime specifier
 --> src/main.rs:7:34
  |
7 | fn fib<T: Zero + One + AddAssign<&T>>(n: usize) -> T {
  |                                  ^ expected lifetime parameter
Run Code Online (Sandbox Code Playgroud)

Rust希望我添加一个生命周期参数,AddAssign<&T>但我不知道如何表达生命周期f1.

Nov*_*zen 9

你需要使用更高级别的特质界限.这基本上意味着"任何一生'a,T满足AddAssign<&'a T>特质":

fn fib<T>(n: usize) -> T
where
    for<'a> T: Zero + One + AddAssign<&'a T>,
Run Code Online (Sandbox Code Playgroud)

我还必须改变fib调用方式,因为编译器无法找出返回类型,这可能实际上是任何实现这些特征的类型.声明x的类型为编译器提供了足够的上下文,以便它知道你想要什么.

fn main() {
    let x: num::BigUint = fib(10);
    // let x = fib::<BigUint>(10); // Also works
    println!("fib(10) = {}", x);
}
Run Code Online (Sandbox Code Playgroud)

操场