如何从函数返回过滤器迭代器? [英] How do I return a Filter iterator from a function?
问题描述
我想要这样的东西:
fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> ??? {
input.iter().filter(|&x| x == Int::one())
}
那个函数的返回类型是什么?(我想返回迭代器)
What's the return type of that function? (I want to return the Iterator)
(我希望这不是太明显,我已经尝试了半个小时,现在开始感到沮丧:p)
(I hope this isn't too obvious, I've been trying for half an hour now and am just starting to get frustrated :p )
我尝试按照这里的说明 => playpen 链接
编译器给了我以下错误:
the compiler gives me the following error:
<anon>:5:1: 7:2 error: the trait `core::kinds::Sized` is not implemented for the type `for<'r> core::ops::Fn(&'r T) -> bool + 'a`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6 input.iter().filter(|&x| x == Int::one())
<anon>:7 }
<anon>:5:1: 7:2 note: required by `core::iter::Filter`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6 input.iter().filter(|&x| x == Int::one())
<anon>:7 }
<anon>:5:1: 7:2 error: the trait `for<'r> core::ops::Fn(&'r &'a T) -> bool` is not implemented for the type `for<'r> core::ops::Fn(&'r T) -> bool + 'a`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6 input.iter().filter(|&x| x == Int::one())
<anon>:7 }
<anon>:5:1: 7:2 note: required by `core::iter::Filter`
<anon>:5 fn filter_one<'a, T: Int>(input: &'a Vec<T>) -> Filter<&T, Iter<'a, T>, Fn(&T) -> bool>{
<anon>:6 input.iter().filter(|&x| x == Int::one())
<anon>:7 }
error: aborting due to 2 previous errors
playpen: application terminated with error code 101
我如何告诉 rustc
Fn(&T) ->bool
是大小?
?
推荐答案
Rust 1.26
fn filter_one(input: &[u8]) -> impl Iterator<Item = &u8> {
input.iter().filter(|&&x| x == 1)
}
fn main() {
let nums = vec![1, 2, 3, 1, 2, 3];
let other: Vec<_> = filter_one(&nums).collect();
println!("{:?}", other);
}
Rust 1.0
fn filter_one<'a>(input: &'a [u8]) -> Box<Iterator<Item = &'a u8> + 'a> {
Box::new(input.iter().filter(|&&x| x == 1))
}
fn main() {
let nums = vec![1, 2, 3, 1, 2, 3];
let other: Vec<_> = filter_one(&nums).collect();
println!("{:?}", other);
}
此解决方案需要额外分配.我们创建了一个盒装特征对象.在这里,对象的大小总是已知的(它只是一两个指针),但不需要知道堆中对象的大小.
This solution requires additional allocation. We create a boxed trait object. Here, the size of the object is always known (it's just a pointer or two), but the size of the object in the heap does not need to be known.
正如Vladimir Matveev 指出的,如果您的谓词逻辑不需要来自环境的任何信息,您可以使用一个函数而不是一个闭包:
As Vladimir Matveev points out, if your predicate logic doesn't need any information from the environment, you can use a function instead of a closure:
use std::{iter::Filter, slice::Iter};
fn filter_one<'a>(input: &'a [u8]) -> Filter<Iter<u8>, fn(&&u8) -> bool> {
fn is_one(a: &&u8) -> bool {
**a == 1
}
input.iter().filter(is_one)
}
fn main() {
let nums = vec![1, 2, 3, 1, 2, 3];
let other: Vec<_> = filter_one(&nums).collect();
println!("{:?}", other);
}
另见:
这篇关于如何从函数返回过滤器迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!