如何写一个特征绑定添加两个泛型类型的引用?
让我们从一个简化的例子开始:
fn add_things(a: &T, b: &T) { a + b; }
这有错误
error[E0369]: binary operation `+` cannot be applied to type `&T`
--> src/lib.rs:2:5
|
2 | a + b;
| ^^^^^
|
= note: an implementation of `std::ops::Add` might be missing for `&T`
正如编译器提示的那样,我们需要保证Add
实现&T
.我们可以通过向我们的类型添加显式生命周期并在我们的特征边界中使用它来直接表达:
use std::ops::Add; fn add_things<'a, T>(a: &'a T, b: &'a T) where &'a T: Add, { a + b; }
接下来,让我们尝试一种稍微不同的方法 - 我们将在函数内部创建一个,而不是提交引用.
fn add_things(a: T, b: T) { let a_ref = &a; let b_ref = &b; a_ref + b_ref; }
我们得到了同样的错误:
error[E0369]: binary operation `+` cannot be applied to type `&T`
--> src/lib.rs:5:5
|
5 | a_ref + b_ref;
| ^^^^^^^^^^^^^
|
= note: an implementation of `std::ops::Add` might be missing for `&T`
但是,尝试添加与以前相同的修复程序不起作用.这也有点尴尬,因为生命周期与传入的任何参数无关:
use std::ops::Add; fn add_things<'a, T: 'a>(a: T, b: T) where &'a T: Add, { let a_ref = &a; let b_ref = &b; a_ref + b_ref; }
error[E0597]: `a` does not live long enough
--> src/lib.rs:7:17
|
3 | fn add_things<'a, T: 'a>(a: T, b: T)
| -- lifetime `'a` defined here
...
7 | let a_ref = &a;
| ^^
| |
| borrowed value does not live long enough
| assignment requires that `a` is borrowed for `'a`
...
11 | }
| - `a` dropped here while still borrowed
将'a
生命周期放在impl
意味着方法的调用者确定生命周期应该是什么的意义上.由于引用是在方法内部进行的,因此调用者甚至无法看到生命周期是什么.
相反,您希望限制任意生命周期的引用实现特征.这被称为更高级别的特质界限(HRTB):
use std::ops::Add; fn add_things(a: T, b: T) where for<'a> &'a T: Add, { let a_ref = &a; let b_ref = &b; a_ref + b_ref; }
应用回原始代码,您非常接近:
implIterator for Fibonacci where T: Clone, for<'a> &'a T: Add
也可以看看:
当其中一个是本地引用时,如何为类型约束中的引用写入生命周期?
<>语法与常规生命周期绑定有何不同?
如何在泛型函数中要求泛型类型实现Add,Sub,Mul或Div等操作?