在Rust中返回一个使用闭包的映射迭代器

15

我正在学习使用Rust解决Matasano Crypto挑战,并在尝试将凯撒密码(“单字节异或”)实现为迭代器时遇到了困难。我的函数应该长这样:

fn ceaser_cipher_iter(data: &Vec<u8>, key :u8) -> SomeType {
    data.iter().map(move |&p| p^key)
}

Replacing `SomeType` with `()` , the compiler tells me what type it expects: `core::iter::Map, [closure src/main.rs:59:21: 59:31]>`. After some investigation, I discovered that I could use `std::slice::Iter` instead of `core::slice::Iter<'_, u8>`, which resolves the issue with the closure.
fn ceaser_cipher_iter(data: &Vec<u8>, key :u8) -> Map<std::slice::Iter<u8>, fn(&u8)->u8 > {
    data.iter().map(move |&p| p^key)
}

无法工作,因为 Rust 需要知道确切的闭包类型以便为闭包分配内存(key 必须通过 move 存储到闭包中)。我尝试按照建议改用 Box

fn ceaser_cipher_iter(data: &Vec<u8>, key :u8) -> Map<std::slice::Iter<u8>, Box<Fn(&u8)->u8> > {
    data.iter().map(Box::new(move |&p| p^key))
}

但据我所知,map不支持它:

src/main.rs:59:17: 59:47 error: the trait `core::ops::FnMut<(&u8,)>` is not implemented for the type `Box<for<'r> core::ops::Fn(&'r u8) -> u8>` [E0277]
src/main.rs:59     data.iter().map(Box::new(move |&p| p^key))
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:59:17: 59:47 error: the trait `core::ops::FnOnce<(&u8,)>` is not implemented for the type `Box<for<'r> core::ops::Fn(&'r u8) -> u8>` [E0277]
src/main.rs:59     data.iter().map(Box::new(move |&p| p^key))
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

有没有一种方法可以使用闭包返回一个映射迭代器?

1个回答

14

关键是不要将闭包括起来,而是将整个迭代器作为一个整体

fn ceaser_cipher_iter<'a>(data: &'a Vec<u8>, key: u8) -> Box<dyn Iterator<Item=u8> + 'a> {
    Box::new(data.iter().map(move |&p| p.key))
}

请注意,由于迭代器使用了borrow(借用),因此我不得不添加生命周期注释以使代码通过borrow检查。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接