Сжатие векторов одного типа приводит к закрытию карты разных типов
Задний план
Учитывая тип варианта перечисления (не копируемый):
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: &AstNode
тогда как заархивированные rhs
элементы принимают тип l: AstNode
. (Обратите внимание на различные объявления в закрывающем кортеже).
Вопросов
Почему это так?
Есть ли способ перебирать элементы вектора по значению, а не по ссылке? Казалось бы, это возможно из наблюдаемого поведения заархивированных элементов.
(В этом примере это различие приводит к небольшой странности в объявлении синтаксиса, но на практике я столкнулся с программой проверки заимствований при передаче ссылочной переменной в функцию)
Отказ от ответственности: я новичок в Rust
Ответы
Этот Iterator::zipметод не делает ничего особенного, он просто объединяет оба итератора. Вы обнаружите, что это lhs.iter()
дает, Iterator<&AstNode>
а время rhs
дает Iterator<AstNode>
( &
против не- &
).
Есть ли способ перебирать элементы вектора по значению, а не по ссылке? Казалось бы, это возможно из наблюдаемого поведения заархивированных элементов.
Да, есть способ контролировать это поведение. Главное - заметить, что zip()
аргумент rhs
должен реализовывать эту IntoIterator
черту. По сути, zip()
вызовет rhs.into_iter()
получение от него итератора. Обычное поведение состоит в том, что заимствует.iter() только источник и поэтому может предоставлять только ссылки на его значения. В то время как потребляет или «становится владельцем» источника и может давать собственные ценности..into_iter()
Комбинируя их, вы можете lhs.into_iter().zip(rhs)
получить итератор по значениям (AstNode, AstNode)
или использовать lhs.iter().zip(rhs.iter())
для получения итератора по ссылкам (&AstNode, &AstNode)
.