Days ago, I came across some codes on this forum(original post gets forgotten by me, but no need to read or review it)
say we have a Rust tree with a find_leafs
method here on playground:
use std::vec;
#[derive(Debug)]
pub struct Tree<T> {
root: Option<TreeNode<T>>,
}
#[derive(Debug)]
pub struct TreeNode<T> {
val: T,
children: Vec<TreeNode<T>>,
}
impl<T> TreeNode<T> {
pub fn new(val: T) -> Self {
Self {
val,
children: vec![],
}
}
pub fn find_leafs(&self) -> Vec<&TreeNode<T>> {
let mut leafs: Vec<&TreeNode<T>> = vec![];
self.find_leafs_r(&mut leafs);
leafs
}
fn find_leafs_r<'a, 'b>(&'a self, lfs: &'b mut Vec<&'a TreeNode<T>>) {
if self.children.len() > 0 {
self.children.iter().for_each(|c| c.find_leafs_r(lfs))
} else {
lfs.push(&self)
}
}
}
impl<T> Tree<T> {
pub fn new() -> Self {
Self { root: None }
}
pub fn find_leafs(&self) -> Vec<&TreeNode<T>> {
if self.root.is_none() {
return vec![];
}
let l = self.root.as_ref().unwrap().find_leafs();
return l;
}
}
This is FINE now
My question is about lifetime constraint:
After changing
fn find_leafs_r<'a, 'b>(&'a self, lfs: &'b mut Vec<&'a TreeNode<T>>) {
// ...
}
to
fn find_leafs_r<'a, 'b: 'a>(&'a self, lfs: &'b mut Vec<&'a TreeNode<T>>) {
// ...
}
it doesn't compile
why is this WRONG?
Based on my understanding, we use lifetime to refer to lifetime of pointee(the one gets pointed) of a borrow
so adding this constraint seems natural:
we need to make sure when we're able to access lfs
(that Vec
), all its contents' pointee (those TreeNode
) don't get erased,
which indicates 'b: 'a
imo
BTW, I've tried to read error of rustc
, but it seems pretty hard to understand