【问题标题】:Idiomatic Rust code for zipped mutable vector iterator用于压缩可变向量迭代器的惯用 Rust 代码
【发布时间】:2015-09-11 13:43:15
【问题描述】:

我在尝试使用 Rust(以惯用方式)时正在执行 Matasano crypto challenge

second assignment 用于异或两个向量。我现在的代码是:

extern crate rustc_serialize;

use rustc_serialize::hex::{FromHex,ToHex};

pub fn fixed_xor(l: &str, r: &str) -> String {
    let mut l = l.from_hex().unwrap();
    let r = r.from_hex().unwrap();
    for i in 0..l.len() {
        l[i] ^= r[i];
    }
    return l.to_hex();
}

这行得通,但由于 for 循环中的范围,它感觉不到惯用代码。

是否可以压缩lr 并从l 获取对元素的可变引用以及从r 获取对元素的非可变引用?

(注意,我不检查向量的长度。我知道这在现实生活中会爆炸,但我现在想专注于 for 循环)

【问题讨论】:

  • 这样的问题最好在 Code Review 中提出,但请read the guide 知道如何在那里提出问题。

标签: vector iterator rust mutable idioms


【解决方案1】:

您可以使用.zip() 迭代器适配器,例如这样:

pub fn xor_in_place(l: &mut [u8], r: &[u8]) {
    for (x, y) in l.iter_mut().zip(r) {
        *x ^= *y;
    }
}

您可以考虑通过以下任一方式推广此 XOR 操作

  1. 接受所有实现BitXor 的元素类型。
  2. 接受通用 IntoIterator 参数,而不仅仅是切片。

注意zip 将在两个迭代器中较短的那个迭代器运行时停止。

【讨论】:

  • 有趣的是,zip 将在两个迭代器中较短的一个迭代器停止时停止,从而避免离开末端的可能性。
  • 是的,这可能是一个微妙的错误。您可能想要断言切片的长度相等。
【解决方案2】:

这是我的解决方案。我相信它涵盖了 Matasano 异或所需的所有情况(假设单字符异或你使用单字节键向量),而且它看起来相对整洁并且与 Rust 教程保持一致。

pub fn xor(text: &Vec<u8>, key: &Vec<u8>) -> Vec<u8> {
    let key_iter = key.iter().cycle();
    text.iter().zip(key_iter).map(|&a, b)| a ^ b ).collect()
}

【讨论】:

  • 您可能有兴趣在 Code Review 上发布您的完整代码,但请read the guide 知道如何在那里提问。例如,没有理由使用&amp;Vec&lt;T&gt;(改用&amp;[T])。此外,a ^ b 之后还有一个非惯用空格。
  • 请注意,此解决方案还返回异或结果的新向量,但原始向量就地变异。除非另有说明,否则我会使用此解决方案。
猜你喜欢
  • 1970-01-01
  • 2017-08-29
  • 2023-03-25
  • 2020-01-05
  • 2021-11-24
  • 2013-08-01
  • 1970-01-01
  • 2015-08-28
相关资源
最近更新 更多