I want to pass a function that takes an arbitrary iterator over some type (e.g. String
in the example below) into another function, but I don't know how to specify the type of such a function.
Here is a minimal (non-working) example of what I'm trying to achieve. The compiler cannot infer the type of I
.
fn process<I>(lines: I)
where
I: Iterator<Item = String>, // or IntoIterator
{
for line in lines {
println!("{}", line.to_uppercase());
}
}
fn run<F, I>(processor: F)
where
I: Iterator<Item = String>,
F: Fn(I),
{
let v = vec![
String::from("aaa"),
String::from("BBB"),
String::from("cCcC"),
];
processor(v.iter());
}
fn main() {
run(process);
}
run
isn't passing any Iterator<Item = String>
it's currently passing a very specific std::slice::Iter<'_, String>
so you can't have a generic I: Iterator
on it. Anyways slice::Iter<'_, String>
implements Iterator<Item = &String>
not Iterator<Item = String>
(note the additional/absent &
) so process
doesn't even accept it.
You probably meant to write this:
fn process<I>(lines: I)
where
I: IntoIterator<Item = String>,
{
for line in lines {
println!("{}", line.to_uppercase());
}
}
fn run<F>(processor: F)
where
F: Fn(std::vec::IntoIter<String>),
{
let v = vec![
String::from("aaa"),
String::from("BBB"),
String::from("cCcC"),
];
processor(v.into_iter());
}
fn main() {
run(process);
}
or this alternative run
:
fn run<F>(processor: F)
where
F: Fn(Vec<String>),
{
let v = vec![
String::from("aaa"),
String::from("BBB"),
String::from("cCcC"),
];
processor(v);
}