How to most generically iterate a sequence of items with a given type?
rust
Solution
Let's look at what the types are for your first case:
for i in &["foo".to_string()] {
let () = i;
// expected `&collections::string::String`,
// found `()`
}
That is, the type of your iteration variable is `&String`, not on `String`, as your function wants. The same thing happens for your second case. The third case works:
for i in vec!["foo".to_string()] {
let () = i;
// expected `collections::string::String`,
// found `()`
}
We can look at the implementation for `IntoIter` for arrays and for all 3 forms of Vec. Note that the implementation for `Vec<T>` consumes the vector, whereas the one for `&Vec<T>` must return an iterator over references to the elements.
You can't consume an array, so that iterator must always return references.
Here's an example that uses the `AsRef` trait that should do what you want:
use std::iter::IntoIterator;
fn iterate<I, S>(v: I)
where I: IntoIterator<Item=S>,
S: AsRef<str>
{}
fn main() {
iterate(&["foo"]);
iterate(&["foo".to_string()]);
iterate(["foo".to_string()].iter());
iterate(vec!["foo".to_string()]);
iterate(&vec!["foo".to_string()]);
}
This says that we expect any concrete type that implements the trait `Iterator`. That iterator must yield a type that implements the trait `AsRef<str>`, allowing us to pass in {arrays,vectors,slices} of {`String`,`&str`}.
Problem
The code below best describes the issue. ``` use std::iter::IntoIterator; fn iterate<I: IntoIterator<Item=String>>(v: I) { } // iterate(&["foo".to_string()]) // error: type mismatch resolving `<&[collections::string::String; 1] as core::iter::IntoIterator>::Item == collections::string::String`: // expected &-ptr, // found struct `collections::string::String` [E0271] // iterate(["foo".to_string()].iter()) // type mismatch resolving `<core::slice::Iter<'_, collections::string::String> as core::iter::IntoIterator>::Item == collections::string::String`: // expected &-ptr, // found struct `collections::string::String` [E0271] // This works ! iterate(vec!["foo".to_string()]) ``` How can I iterate anything (with a given item type) generically? Additional Notes The intention is to allow users of such a function to pass in anything that can be iterated, or converted into an iterator. Also I have the feeling that the actual issue is not really described in the compiler error - as the type it sees seems to be different from what it shows. I am using `rustc 1.0.0-nightly (522d09dfe 2015-02-19) (built 2015-02-19)`