压缩相同类型的向量会导致地图闭包中的不同类型

nic*_*las 2 vector rust

背景

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

enum AstNode {
  Op(Func, Box<AstNode>, Box<AstNode>),
  Val(f64),
  // others...
}
Run Code Online (Sandbox Code Playgroud)

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

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!
}
Run Code Online (Sandbox Code Playgroud)

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

问题

为什么会这样?

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

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

免责声明:我是 Rust 的新手

kmd*_*eko 6

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

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

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

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