我正在尝试在Rust中实现BST(适用于Rust中{3}}可爱介绍中的HW3),我遇到了生命周期中的错误,以及如何限制与类型相关的类型的生命周期没有一生。
#[derive(Debug)]
pub struct BST<T>
where T: Ord
{
root: Option<Box<Node<T>>>,
}
// A couple dozen lines of BST stuff
impl<'a, T> IntoIterator for BST<T>
where T: Ord
{
type Item = T;
type IntoIter = BSTIter<'a, T>; // <- my intuition is that I should
// be able to say "BSTIter lives as
// long as BST."
fn into_iter(&'a mut self) -> BSTIter<'a, T> {
BSTIter::new(&mut self)
}
}
pub struct BSTIter<'a, T: 'a>
where T: Ord + 'a
{
bst: &'a mut BST<T>,
node_list: Vec<&'a Node<T>>, // this is where the need for a lifetime on
// BSTIter comes from
}
impl<'a, T> BSTIter<'a, T>
where T: Ord
{
fn new(&mut bst: BST<T>) -> BSTIter<'a, T> {
let traverse_stack = Vec::new();
if let Some(ref x) = bst.root {
traverse_stack.push(x);
}
BSTIter {
bst: bst,
node_list: traverse_stack,
}
}
}
impl<'a, T> Iterator for BSTIter<'a, T>
where T: Ord
{
type Item = T;
fn next(&mut self) -> Option<T> {
// BST iteration details
}
}
就目前而言,此代码会吐出错误
error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates
--> src/lib.rs:117:7
|
117 | impl<'a, T> IntoIterator for BST <T> where T: Ord {
| ^^ unconstrained lifetime parameter
如果IntoIterator
特征不要求我指定type IntoIterator = BSTIter
,则实施块可能只有into_iter
方法签名into_iter<'a>(&'a mut self) -> BSTIter<'a, T>
。由于我需要指定BSTIter
的生命周期,似乎我需要为整个BST类型指定生命周期。再一次,我的直觉说我不应该在BST上指定一个生命周期来为它创建一个迭代器。
我意识到这两个解决方案可能是
中的一个(或两个)如果我可以获得有关如何使上述代码段工作的帮助,或者我应该如何处理这些生命周期和所有权详细信息,那将非常感谢!
答案 0 :(得分:3)
您误解了IntoIterator
的目的和用法。它将值转换为迭代器; 消耗过程中的值。但是,您的迭代器正在尝试返回对集合的引用。 You cannot return references into the iterator,因此使用树,将所有权转移到迭代器是没有意义的。
您称之为BSTIter
而不是BSTIntoIter
这一事实表明了承诺;因为它是返回引用的迭代器的惯用名。
您希望为IntoIterator
实施&'a BST<T>
,而不是BST<T>
。你可以 为BST<T>
实现它,但是你想要产生T
,而不是&T
。
在修复之后,出现了很多编译错误:整个代码中的类型不匹配,特征中的方法签名不正确(fn into_iter(self)
只允许你),出于某种原因,有&#39; sa对树的可变引用,变量应该是可变的......
#[derive(Debug)]
struct Node<T>(Option<Box<T>>);
#[derive(Debug)]
pub struct BST<T>
where T: Ord
{
root: Option<Box<Node<T>>>,
}
impl<'a, T> IntoIterator for &'a BST<T>
where T: Ord
{
type Item = T;
type IntoIter = BSTIter<'a, T>;
fn into_iter(self) -> BSTIter<'a, T> {
BSTIter::new(self)
}
}
pub struct BSTIter<'a, T: 'a>
where T: Ord + 'a
{
bst: &'a BST<T>,
node_list: Vec<&'a Node<T>>,
}
impl<'a, T> BSTIter<'a, T>
where T: Ord
{
fn new(bst: &'a BST<T>) -> BSTIter<'a, T> {
let mut traverse_stack = Vec::new();
if let Some(ref x) = bst.root {
traverse_stack.push(&**x);
}
BSTIter {
bst: bst,
node_list: traverse_stack,
}
}
}
impl<'a, T> Iterator for BSTIter<'a, T>
where T: Ord
{
type Item = T;
fn next(&mut self) -> Option<T> {
None
}
}
fn main() {}