Hi folks,
I implemented for IntoIterator
for a &Tree
only (I didn't implement it for Tree
). The reason is simply that I don't need it and since the elements are stored in a boxed slice, the consuming iterator would need to copy the elements and I don't need that.
One thing I'm confused is how to set lifetimes.
I think the following would be wrong:
T: Clone + Default + IntoIterator<Item = &'a Leaf>
and it should be:
T: Clone + Default + 'a,
&'a T: IntoIterator<Item = &'a Leaf>,
Could you please tell me if that's correct?
All code:
use std::{slice, vec};
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct Leaf {
name: String,
}
impl Leaf {
fn new(name: String) -> Self {
Self { name }
}
fn name(&self) -> &str {
self.name.as_ref()
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct Tree {
leafs: Box<[Leaf]>,
}
impl Tree {
fn new(leafs: Vec<Leaf>) -> Self {
Self {
leafs: leafs.into_boxed_slice(),
}
}
fn iter(&self) -> slice::Iter<'_, Leaf> {
self.leafs.iter()
}
}
impl<'a> IntoIterator for &'a Tree {
type Item = &'a Leaf;
type IntoIter = slice::Iter<'a, Leaf>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct Forest;
impl Forest {
fn get_leafs<'a, T>(tree: &'a T) -> Vec<String>
where
T: Clone + Default + 'a,
&'a T: IntoIterator<Item = &'a Leaf>,
// T: Clone + Default + IntoIterator<Item = &'a Leaf>
{
tree.into_iter().map(|x| x.name().to_owned()).collect()
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
struct BigForest;
impl BigForest {
fn get_leafs<'a, T>(trees: &'a [T]) -> Option<Vec<String>>
where
T: Clone + Default + 'a,
&'a T: IntoIterator<Item = &'a Leaf>,
// T: Clone + Default + IntoIterator<Item = &'a Leaf>
{
match trees {
&[] => None,
&[ref first_tree, ..] => Some(Forest::get_leafs(first_tree)),
}
}
}
fn main() {
let tree = Tree::new(vec![
Leaf::new("first".to_owned()),
Leaf::new("second".to_owned()),
Leaf::new("third".to_owned()),
]);
let another_tree = Tree::new(vec![
Leaf::new("first".to_owned()),
Leaf::new("second".to_owned()),
Leaf::new("third".to_owned()),
]);
let x: Vec<_> = tree.into_iter().map(|leaf| leaf.name()).collect();
println!("{:?}", x);
let x = Forest::get_leafs(&tree);
println!("{:?}", x);
let x = BigForest::get_leafs(&[tree, another_tree]);
println!("{:?}", x);
}