【问题标题】:Zipping vectors of the same type results different types within map closure相同类型的压缩向量会在地图闭包中产生不同的类型
【发布时间】:2020-08-15 21:20:01
【问题描述】:

背景

给定一个枚举变体类型(不可复制):

enum AstNode {
  Op(Func, Box<AstNode>, Box<AstNode>),
  Val(f64),
  // others...
}

尝试对两个这样的向量运行操作:

fn apply_func_iterative(func: Func, lhs: Vec<AstNode>, rhs: Vec<AstNode>) -> Vec<AstNode> {
    lhs.iter().zip(rhs).map(|(&l,r)| apply_func(func,l,r)).collect()  // l and r are declared differently!
}

fn apply_func(func: Func, lhs: AstNode, rhs: AstNode) -> AstNode {
    // magic happens here!
}

在闭包中,lhs 元素采用 l: &amp;AstNode 类型,而压缩后的 rhs 元素采用 l: AstNode 类型。 (注意闭包元组中的不同声明)。

问题

为什么会这样?

有没有办法通过值而不是引用来迭代向量的元素? 从观察到的压缩元素的行为来看,这似乎是可能的。

(在这个例子中,这种差异导致语法声明有点奇怪,但在实践中,我在将引用变量传递给函数时遇到了借用检查器)

免责声明:我对 Rust 还很陌生

【问题讨论】:

    标签: vector rust


    【解决方案1】:

    Iterator::zip 方法没有做任何特别的事情,它只是结合了两个迭代器。您会发现lhs.iter() 产生Iterator&lt;&amp;AstNode&gt;rhs 产生Iterator&lt;AstNode&gt;&amp; 与非&amp;)。

    有没有办法通过值而不是引用来迭代向量的元素?从观察到的压缩元素的行为来看,这似乎是可能的。

    是的,有一种方法可以控制这种行为。关键是要注意zip() 的参数rhs 必须实现IntoIterator 特征。此外,zip() 将调用 rhs.into_iter() 以从中获取迭代器。常规行为是.iter()借用源,因此只能提供对其值的引用。而.into_iter()消耗“拥有”源并且可以产生拥有的价值。

    结合这些,您可以使用lhs.into_iter().zip(rhs) 来获取值(AstNode, AstNode) 的迭代器,或使用lhs.iter().zip(rhs.iter()) 获取引用(&amp;AstNode, &amp;AstNode) 的迭代器。

    【讨论】:

    • 您也可以传递对 rhs 的引用,例如。 lhs.iter().zip(&amp;rhs),由于 IntoIterator&amp;'a [T] 的一揽子实现,它在 &amp;T 上返回一个迭代器。
    • 感谢您对 iter()into_iter() 的见解 - 阅读此事后完全有意义;和 +1 用于提供通过引用进行压缩的反向示例。
    猜你喜欢
    • 2023-04-01
    • 2014-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多