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

标签 generics rust lifetime

我想实现一个通用的 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 .这基本上意味着“对于任何生命周期 'aT 满足 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);
}

playground

关于generics - 如果我在函数内部创建引用,如何将泛型类型与需要生命周期参数的特征绑定(bind)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47996700/

相关文章:

rust - 如何防止移入功能的 impl Trait 在借用时被删除?

java - 什么时候需要为集合指定泛型类型?

java - 识别内置功能接口(interface)

Java:如何推导嵌套泛型类型

rust - 如何禁用 "unnecessary path disambiguator"警告?

rust - 使用不能声明为静态的函数在运行时初始化可变静态变量

c# - 当一切都在编译时已知时,为什么我不能将 nameof 与泛型一起使用?

rust - 已弃用的别名不会生成警告

rust - 为什么在带生命周期注释的 impl block 中的构造函数中创建时借用的值不能存活足够长的时间?

rust - 函数返回 serde 反序列化类型时如何修复生命周期错误?