【发布时间】:2021-03-21 09:51:17
【问题描述】:
考虑以下代码,强调children_iter():
use std::collections::HashMap;
type NodeMap = HashMap<i32, Node>;
struct Node {
id: i32,
parent: Option<i32>,
sibling: Option<i32>,
children: Vec<i32>,
content: String,
}
pub struct NodeIterator<'a> {
nodes: &'a NodeMap,
current: &'a Node,
}
impl<'a> NodeIterator<'a> {
fn new(node: &'a Node, nodes: &'a NodeMap) -> NodeIterator<'a> {
NodeIterator {
nodes,
current: node,
}
}
pub fn children_iter(&self) -> impl Iterator<Item = NodeIterator> {
self.current
.children
.iter()
.map(|i| self.nodes.get(i).unwrap())
.map(|n| Self::new(n, self.nodes))
}
}
此代码的编译失败:
error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function
--> src/lib.rs:30:18
|
30 | .map(|i| self.nodes.get(i).unwrap())
| ^^^ ---- `self` is borrowed here
| |
| may outlive borrowed value `self`
|
note: closure is returned here
--> src/lib.rs:26:36
|
26 | pub fn children_iter(&self) -> impl Iterator<Item = NodeIterator> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
|
30 | .map(move |i| self.nodes.get(i).unwrap())
| ^^^^^^^^
error[E0373]: closure may outlive the current function, but it borrows `self`, which is owned by the current function
--> src/lib.rs:31:18
|
31 | .map(|n| Self::new(n, self.nodes))
| ^^^ ---- `self` is borrowed here
| |
| may outlive borrowed value `self`
|
note: closure is returned here
--> src/lib.rs:26:36
|
26 | pub fn children_iter(&self) -> impl Iterator<Item = NodeIterator> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `self` (and any other referenced variables), use the `move` keyword
|
31 | .map(move |n| Self::new(n, self.nodes))
| ^^^^^^^^
有没有办法正确指定生命周期,以便清楚地知道返回的迭代器仅在当前NodeIterator 的生命周期内有效?
【问题讨论】:
-
-> impl Iterator<Item = NodeIterator>没有意义你的意思是改写-> impl Iterator<Item = Node>吗? -
我不这么认为。我希望返回的迭代器生成
NodeIterator值,而不是Node,这样我就可以通过进一步调用每个生成的值上的children_iter()继续向下递归树。也许令人困惑的是,NodeIterator 有一个额外的功能可以访问content的Node,但我把它去掉了,因为我认为它不相关。你介意解释为什么它没有意义吗?可能是我想错了。 -
返回迭代器的迭代器有点不寻常,但我想如果它有效,那么它就有效。更常见和标准的方法是编写一个迭代整个数据结构的迭代器。
标签: rust closures lifetime borrow-checker borrowing