How often is a sequence of elements with a given type repeated?

The code below describes the problem best.

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 repeat anything (with a given element type) in general?

Additional notes

The goal is to allow users of such a function to pass everything that can be iterated, or converted to an iterator.

I also get the feeling that the actual problem is not actually described in the compiler error - since the view that 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)

+5
source share
1 answer

See what 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 &String is 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 see the implementation for IntoIter for arrays and for all 3 forms of Vec . Note that the implementation for Vec<T> consumes a vector, while for &Vec<T> should return an iterator over the links to the elements.

You cannot use an array so that the iterator always returns links.

Here is an example that uses AsRef , which 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 suggests that we are expecting a specific type that implements the Iterator trait. This iterator should AsRef<str> type that implements the AsRef<str> trait, allowing us to pass {arrays, vectors, slices} from { String , &str }.

+8
source

Source: https://habr.com/ru/post/1213872/


All Articles