允许参考生命周期比关闭更长

时间:2015-05-24 18:58:15

标签: rust

我正试图通过尝试实现单链表来处理Rust。以下是我的数据结构:

struct Linked<T> {
    head: Option<Box<Node<T>>>
}

struct Node<T> {
    data: T,
    next: Option<Box<Node<T>>>
}

现在,我想为此添加一个迭代器:

struct LinkedIter<'a, T: 'a> {
    node: Option<&'a Node<T>>,
}

我为.iter()编写了一个Linked<T>方法,该方法可以编译并正常工作。

impl<T> Linked<T> {
    fn iter(&self) -> LinkedIter<T> {
        LinkedIter { node: match self.head {
                Some(ref node) => Some(&**node),
                None           => None
            }
        }
    }
}

现在,此match块正在将Option<Box<Linked<T>>>转换为Option<&Linked<T>>。这正是Option::map()方法的用途。因此,我使用head.as_ref()代替head重新实现了此方法,以避免在闭包中取得Option内容的所有权。

impl<T> Linked<T> {
    fn iter(&self) -> LinkedIter<T> {
        LinkedIter { node:
            self.head.as_ref().map(|b: &Box<Node<T>>| &**b)
        }
    }
}

不幸的是,闭包中创建的引用不能超过闭包,因为它引用了作为参数传递给闭包的东西。编译器抱怨(转述一下):

  

错误:由于要求冲突,无法推断借用表达式的适当生命周期:

     

首先,生命周期不能超过[在闭包]中定义的匿名生命#1

     

但是,生命周期必须对[iter函数的生命周期]

有效      

以便[node:]表达式可分配

如何向编译器解释在闭包结束后引用仍然有效?

(Playground)

1 个答案:

答案 0 :(得分:3)

这个想法是告诉编译器你在map()中引用的引用和迭代器一样长。我得到了这样的工作:

impl<T> Linked<T> {
    fn iter<'a>(&'a self) -> LinkedIter<T> {
        LinkedIter { node:
            self.head.as_ref().map(|b: &'a Box<Node<T>>| &**b)
        }
    }
}