返回一个在 Rust 中使用闭包的映射迭代器 [英] Return a map iterator which is using a closure in Rust

查看:58
本文介绍了返回一个在 Rust 中使用闭包的映射迭代器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习一些 Rust 来解决 Matasano 加密挑战,并且坚持将 Ceasar 密码(单字节异或")实现为迭代器.我的函数应该是这样的:

I'm learning some Rust solving the Matasano Crypto Challenges and am stuck with implementing the Ceasar cipher ("single-byte xor") as an iterator. My function is supposed to look like this:

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

() 替换 SomeType,编译器告诉我它期望什么类型:core::iter::Map<core::slice::Iter<'_, u8>, [关闭 src/main.rs:59:21: 59:31]>.经过一番折腾后,我发现我可以使用 std::slice::Iter<u8> 作为 core::slice::Iter<'_, u8> ,它留下关闭.据我了解,我使用的幼稚实验

Replacing SomeType with (), the compiler tells me what type it expects: core::iter::Map<core::slice::Iter<'_, u8>, [closure src/main.rs:59:21: 59:31]>. After some headbanging I found out I could use std::slice::Iter<u8> for core::slice::Iter<'_, u8>, which leaves the closure. As far as I understand, my naive experiment to use

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 必须通过被 moved 存储到闭包中).我尝试按照 建议 使用 Box 代替:

cannot work, because Rust needs to know the exact closure type to allocate the memory for the closure (key has to be stored by being moved into the closure). I've tried to follow the advice to use a Box instead:

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))
}

但是 afaict map 不支持它:

But afaict map does not support it:

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))
                               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

有没有办法返回带有闭包的地图迭代器?

推荐答案

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

The trick is not to box the closure, but the iterator as a whole.

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))
}

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

Note that because the iterator uses a borrow, I had to add lifetime annotations so that the code would pass borrow checking.

这篇关于返回一个在 Rust 中使用闭包的映射迭代器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆