The trait bound `Vec<&str>: ExactSizeIterator` is not satisfied

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?

Vec itself is bot.an iterator, and IIRC neither is a reference to it.

Try passing .iter() on it

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.

  1. Just use a slice if you don't really need to support fixed-size-but-not-contiguous types. &[impl Display].

  2. Use a bound like IntoIterator<Item=D, IntoIter=I> where D: Display, I: ExactSizeIterator

  3. 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));
  }
2 Likes

Works as expected! Thanks a lot man!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.