I'm trying to write a function that takes multiple strings and processes them. For simplicity, let's just say I want to print them. The basic function is easy:
fn out(strings) {
for s in strings {
println!("{}", s);
}
}
The problem I have here is getting the type for strings
correct. I could just put : u32
in and let the compiler tell me, but my problem is that I want to keep things general. In particular, I would like to be able to write:
let data = vec!["one", "two"];
out(data);
for testing, but
out(std::env::args().skip(1)
for the real code.
And I don't want to hard code something as specific as std::iter::Skip<std::env::Args>
... Also, I want to keep things reasonably efficient - so I'd like to avoid generating multiple copies of the code if I don't need to, and I'd like to avoid copying the strings to the heap if I don't have to. These aren't hard and fast requirements - for my actual code, I could just make a Vec<String>
and stop obsessing, but it bugs me to do that just because I don't know how to do it more generically. Once I do know what the generic solution looks like, I may decide it's more complex than I need in this case, and go with the simple solution, of course
I think what I need is a generic, something like
fn out<I>(strings: I) -> ()
where I: Iterator<Item=&str>
{
/* Same code as before */
}
But that doesn't work:
Compiling playground v0.0.1 (/playground)
error[E0637]: `&` without an explicit lifetime name cannot be used here
--> src/main.rs:5:24
|
5 | where I: Iterator<Item=&str>
| ^ explicit lifetime name needed here
error[E0277]: `std::vec::Vec<&str>` is not an iterator
--> src/main.rs:14:9
|
4 | fn out<I>(strings: I) -> ()
| ---
5 | where I: Iterator<Item=&str>
| ------------------- required by this bound in `out`
...
14 | out(data);
| ^^^^ `std::vec::Vec<&str>` is not an iterator
|
= help: the trait `std::iter::Iterator` is not implemented for `std::vec::Vec<&str>`
error[E0271]: type mismatch resolving `<std::iter::Skip<std::env::Args> as std::iter::Iterator>::Item == &'static str`
--> src/main.rs:15:5
|
4 | fn out<I>(strings: I) -> ()
| ---
5 | where I: Iterator<Item=&str>
| --------- required by this bound in `out`
...
15 | out(env::args().skip(1));
| ^^^ expected `&str`, found struct `std::string::String`
I think what I need is to be able to say "something that can be converted to an Iterator
whose item type can be converted to a &str`. But I don't know how to do that, and I don't know what terms I should be searching for.
Can anyone give me any pointers - to either the correct approach, or to some search terms I can use to look for hints?