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

Per*_*ids 7 rust

我正在学习一些解决Matasano Crypto挑战的Rust,并坚持使用Ceasar密码("单字节xor")作为迭代器.我的函数应该是这样的:

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

替换SomeType(),编译器告诉我它所期望的类型:core::iter::Map<core::slice::Iter<'_, u8>, [closure src/main.rs:59:21: 59:31]>.一些撞头后,我发现我可以用std::slice::Iter<u8>core::slice::Iter<'_, u8>,这让关闭.据我了解,我的天真实验使用

fn ceaser_cipher_iter(data: &Vec<u8>, key :u8) -> Map<std::slice::Iter<u8>, fn(&u8)->u8 > {
    data.iter().map(move |&p| p^key)
}
Run Code Online (Sandbox Code Playgroud)

无法工作,因为Rust需要知道确切的闭包类型来为闭包分配内存(key必须通过将moved存入闭包来存储).我试图按照建议使用一个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))
}
Run Code Online (Sandbox Code Playgroud)

但是afaict 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))
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

有没有办法用闭包返回一个map迭代器?

DK.*_*DK. 6

诀窍不是将封闭盒装箱,而是将迭代器作为一个整体

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

注意,因为迭代器使用借位,所以我必须添加生命周期批注,以便代码可以通过借位检查。