首页 > 解决方案 > 相同类型的压缩向量会在地图闭包中产生不同的类型

问题描述

背景

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

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元素采用 type l: &AstNode,而 zippedrhs元素采用 type l: AstNode。(注意闭包元组中的不同声明)。

问题

为什么会这样?

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

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

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

标签: vectorrust

解决方案


Iterator::zip方法没有做任何特别的事情,它只是结合了两个迭代器。您会发现lhs.iter()产生一个Iterator<&AstNode>whilerhs产生一个Iterator<AstNode>( &vs non- &)。

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

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

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


推荐阅读