返回由闭包借用自我产生的迭代器的函数的正确返回类型是什么

让·卢克

考虑以下代码,重点是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

椒盐脆饼

您收到此错误的原因是因为在Rust中,迭代器是lazy-evaluated的看起来您的闭包将在children_iter函数中执行,但实际上直到调用者next在返回的迭代器上调用方法后,闭包才真正执行

编译器建议使用move关键字将借用的引用移至闭包中,从而解决了该问题。但是,您也可以通过热切评估迭代器并将结果收集到中来解决此问题Vec<NodeIterator>这是固定和编译示例中的两种方法:

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()
            // lazily-evaluted closures
            // they run in the caller's scope
            .map(move |i| self.nodes.get(i).unwrap())
            .map(move |n| Self::new(n, self.nodes))
    }
    
    pub fn children_iter_vec(&self) -> Vec<NodeIterator> {
        self.current
            .children
            .iter()
            // eagerly-evaluted closures
            // we run them in the current scope
            .map(|i| self.nodes.get(i).unwrap())
            .map(|n| Self::new(n, self.nodes))
            .collect()
    }
}

操场

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

此Rust函数返回的迭代器类型是什么?

返回闭包的函数的正确语法

从函数返回的C ++类型的lambda闭包

Rust函数的返回类型闭包

从函数返回闭包

返回自身的函数的返回类型是什么?

尝试更改返回迭代器的闭包内的状态时,Rust错误“无法为借用表达式推断适当的生存期”

我可以告诉PhpStorm函数的返回类型是什么吗?

路由器函数的返回类型是什么?

返回函数与返回闭包

有什么办法从闭包内部从函数返回吗?

要构建的正确返回类型是什么?

JavaScript闭包-帮助我理解为什么内部函数的返回值不返回

让成员函数返回类型成为要返回的实际对象的超类的正确方法是什么?

为什么我不能从闭包中返回引用?

如何返回借用状态供以后使用的 Rust 闭包?

从函数返回的正确方法是什么?

什么是反向函数返回的“迭代器对象”?

将类型传递给函数以返回返回该类型的闭包?

函数的返回类型中{}的目的是什么?

从嵌套组件返回映射迭代器的正确方法是什么?

返回可迭代的服务器角色的正确操作是什么?

从函数内的闭包内的闭包中返回数据

返回C ++中的闭包类型

返回闭包但无法推断类型

返回类型'Map <String,Dynamic>'不是字符串,由匿名闭包定义

为什么Swift闭包无法捕获自我?

从迭代器推导值类型以获取模板函数的返回类型

返回 AsyncFunction 的 Typescript 函数的适当返回类型是什么?