Iterator adapters that takes a function pointer


#1

I would like to implement a function like this

fn changed_ch_vals(&self) -> Map<Filter<Iter<'a, Channel>, fn(&Channel)->bool>, fn(&Channel)->ChVal> { self.needs_update = false; self.channels.iter() .filter(Channel::is_changed()) .map(Channel::get_ch_val()) }

Something that borrows elements from a vector into an iterator, does some manipulation on it and passes the transformed iterator to someone else that does other operations.
It would be very easy if the adapters had also a version that takes a proper function instead of a closure because I can’t (or I don’t know how) use a closure in the type parameter.
So why it isn’t there? And how could I get it work?
Thank you in advance


#2

You can! fn(...) -> _ implements Fn(...) -> _. For example (https://is.gd/yK50vF)

use std::{ iter, vec };

fn foo(u: u8) -> i8 {
    u as i8
}

fn bar(v: Vec<u8>) -> iter::Map<vec::IntoIter<u8>, fn(u8) -> i8> {
    v.into_iter().map(foo)
}

fn main() {
    for i in bar(vec![1, 2, 255]) {
        println!("{}", i);
    }
}

In your example you’re calling the Channel::is_changed and Channel::get_ch_val functions with no arguments, assuming they match the function signatures in your function declaration you should be able to just drop the () off the call to take the value of the functions.

EDIT: One issue that sometimes crops up with this is that every function pointer has it’s own type, e.g. the type of foo in my example is fn(u8) -> i8 {foo}. They should automatically cast to the ‘generic’ function pointer type, but occasionally this breaks, when this happens you can normally work around it by give the type inference engine a nudge using something like v.into_iter().map(foo as _).