Rust using chain after String.split

Viewed 309

I have this piece of code that works:

for line in content
    .split('\n')
    .collect::<Vec<_>>()
    .iter()
    .chain((&["output"]).iter())

I think there must be a way to use the iterator provided by split to obtain the same result without having to collect() into a vector.

When I try to change .collect::<Vec<_>>().iter() to into_iter() I get the following error:

error[E0271]: type mismatch resolving `<std::slice::Iter<'_, &str> as IntoIterator>::Item == &str`
   --> src/main.rs:251:53
    |
251 |         for line in content.split('\n').into_iter().chain((&["output"]).iter()) {
    |                                                     ^^^^^ expected `&str`, found `str`
    |
    = note: expected reference `&&str`
               found reference `&str`

There are also other errors referring to the same line that basically say the same thing.

1 Answers

The core of the problem is:

  • (&["output"]).iter() is type std::slice::Iter<'_, &str> which has Item=&&str.
  • content.split('\n') is type std::str::Split<'_, char> which has Item=&str.

So the item types do not match. If you make the types match it compiles, IMO the easiest is to use map on the array to dereference each string.

    for line in content
        .split('\n')
        .chain((&["output"]).iter().map(|s|*s)) {
            println!("line={}",line);
       }

I found this by inserting lines of the form let q:() = ... which gave me

21 |     let q:() = (&["output"]).iter();   
   |           --   ^^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `std::slice::Iter`
   |           |
   |           expected due to this
   |
   = note: expected unit type `()`
                 found struct `std::slice::Iter<'_, &str>`
22 |     let q:() = content.split('\n');
   |           --   ^^^^^^^^^^^^^^^^^^^ expected `()`, found struct `std::str::Split`
   |           |
   |           expected due to this
   |
   = note: expected unit type `()`
                 found struct `std::str::Split<'_, char>`

Then followed these up by let q: <X as Iterator>::Item = ()

23 |     let q: <std::slice::Iter<&str> as Iterator>::Item = ();
   |            ------------------------------------------   ^^ expected `&&str`, found `()`

and

24 |     let q: <std::str::Split<char> as Iterator>::Item = ();
   |            -----------------------------------------   ^^ expected `&str`, found `()`
Related