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

时间:2017-12-27 18:05:36

标签: generics rust lifetime

我想实现一个通用ArrayAdapter adapter = new ArrayAdapter<>(SearchFriendsActivity.this, android.R.layout.simple_list_item_1, usersList1234); this.allUsers.setAdapter(adapter); 函数,该函数适用于实现fibonacciZeroOne的任何类型。我首先实现了一个工作正常的版本,但专门用于AddAssignsee on play.rust-lang.org)。我想出了以下通用实现(see on play.rust-lang.org):

num::BigUint

这不编译:

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
}

Rust希望我向error[E0106]: missing lifetime specifier --> src/main.rs:7:34 | 7 | fn fib<T: Zero + One + AddAssign<&T>>(n: usize) -> T { | ^ expected lifetime parameter 添加一个生命周期参数,但我不知道如何表达AddAssign<&T>的生命周期。

1 个答案:

答案 0 :(得分:7)

您需要使用Higher Rank Trait Bounds。这个基本上意味着&#34;对于任何生命周期'aT都满足AddAssign<&'a T>特征&#34;:

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);
}

playground