这段代码定义了一个非常简单的特征来表示二叉树,以及实现该特征的结构体:
pub trait BTree<T> {
fn all(&self) -> Option<(&Self, &Self, &T)>;
fn left(&self) -> Option<&Self>;
fn right(&self) -> Option<&Self>;
fn value(&self) -> Option<&T>;
}
pub struct MyBTree<T> {
opt: Option<Box<(MyBTree<T>, MyBTree<T>, T)>>,
}
impl<T> BTree<T> for MyBTree<T> {
fn all(&self) -> Option<(&Self, &Self, &T)> {
match self.opt {
None => None,
Some(ref tuple) => Some((&tuple.0, &tuple.1, &tuple.2)),
}
}
fn left(&self) -> Option<&Self> {
match self.all() {
None => None,
Some((left, _, _)) => Some(left),
}
}
fn right(&self) -> Option<&Self> {
match self.all() {
None => None,
Some((right, _, _)) => Some(right),
}
}
fn value(&self) -> Option<&T> {
match self.all() {
None => None,
Some((_, _, value)) => Some(value),
}
}
}
left
,right
和value
的实现可以移动到特质内部,因为它们仅依赖于特质定义的all
方法,而不依赖于具体实现细节。
这适用于value
,但对于left
和right
则不适用。例如,如果我尝试将left
的实现移到特质的主体中,那么我会得到以下编译错误:
error[E0311]: the parameter type `T` may not live long enough
--> src/lib.rs:6:24
|
6 | match self.all() {
| ^^^
|
= help: consider adding an explicit lifetime bound for `T`
note: the parameter type `T` must be valid for the anonymous lifetime #1 defined on the method body at 5:9...
--> src/lib.rs:5:9
|
5 | / fn left(&self) -> Option<&Self> {
6 | | match self.all() {
7 | | None => None,
8 | | Some((left, _, _)) => Some(left),
9 | | }
10| | }
| |_________^
note: ...so that the reference type `&T` does not outlive the data it points at
--> src/lib.rs:6:24
|
6 | match self.all() {
|
为什么这个问题出现在trait中而不是MyBTree
的实现中?
为什么编译器会抱怨在忽略T值的方法中T的生命周期,但是在返回类型中提到T的value
方法可以正常工作?
#![feature(nll)]
进行编译。 - Tim Diekmannfn f<'a, 'b>() { let _: &'a &'b (); }
- dtolnayBTree
特质的多个实例,否则我建议使用关联类型版本。这样,当您编写使用BTree
的通用函数时,您不需要为BTree
的T
添加额外的类型参数。 - Francis Gagné