I want something like that:
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)
(I hope this isn't too obvious, I've been trying for half an hour now and am just starting to get frustrated :p )
EDIT:
I tried to follow the instructions from here => playpen link
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
How do I tell rustc
that Fn(&T) -> bool
is Sized?
?
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); }
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.
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); }
See also:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With