String splitting issue

fn main()
{
    let my_string = String::from("one+two+three");
    let my_string_vec: Vec<&str> = my_string.split("+").collect(); // Why I can't use String data type instead

    for word in my_string_vec.iter()
    {
        print!("{} ", word);
    }
}

In this line let my_string_vec: Vec<&str> = my_string.split("+").collect(); why can't I use String data type inside the vector when using the collect() method?

Because iterator returned from split gives you &strs. To get String from &str, you must convert it explicitly.

3 Likes

(Edit: this is slightly incorrect; see @Hyeonu‘s post below for a correction)

As @Cerberuser said, split returns Vec<&str>; if you want something different, you need to convert it explicitly.

At an API design level, split returns &strs because it can only ever produce substrings of the input. To return Strings, it would need to do a potentially-unnecessary copy.

This is a pattern you’ll see in all sorts of Rust APIs: they won’t make copies themselves unless it’s absolutely required to do their job. It’s the caller’s responsibility to decide whether or not to copy things, based in whether or not they’ll be needed later.

2 Likes

Strictly speaking the .split("+") returns a struct which impls Iterator<Item = &str>. It doesn't allocates vector by itself, it even doesn't search the string until you consume the iterator. It's called lazy evaluation.

4 Likes

I should’ve guessed that; I was too lazy to actually look it up in the docs this time.

2 Likes