I just finished the chapter in the book about "Traits" and I'm trying to create a function but it doesn't work as expected. The code goes like that:
pub fn unfold_all<T: ExactSizeIterator + Index<usize, Output = T> + Display>(col: &T) -> String {
let mut result = String::new();
result.push_str(&format!("[{}", &col[0]));
for i in 1..col.len() {
result.push_str(&format!(", {}", &col[i]));
} result.push(']');
result
}
let mut unrec_opt: Vec<&str> = Vec::new();
// error is a function that takes a "String"
error(format!("the following options are not recognized: {}", unfold_all(&unrec_opt)));
When I try to run this code, I get the following the title message in the title of this post (of course that's only a part of it). However when I try to use this function without generics and instead have it accept a &Vec<&str> as the parameter, it works without any problems. So can someone explain my what's going on?
I suppose you mean error(format!("the following escape sequences are not recognized: {}", unfold_all(unrec_seq.iter())));. I did it and I get the same result.
Collections index themselves (implement Index), but they never iterate themselves (iterator is always another object). So Index + Iterator requirement can't be satisfied by any standard collection.
Plus you have T: Index<Output = T>, which requires the type to return itself, which it can't.
Just use a slice if you don't really need to support fixed-size-but-not-contiguous types. &[impl Display].
Use a bound like IntoIterator<Item=D, IntoIter=I> where D: Display, I: ExactSizeIterator
In your case you can actually just use a regular iterator and call iter.next() to get the first element, and then loop over the rest. No need to know length or use [i] anywhere.
fn unfold(mut iter: impl Iterator<Item=impl Display>) {
…
result.push_str(&format!("[{}", iter.next().expect("oops, empty")));
for el in iter {
result.push_str(&format!(", {}", el));
}