Splitting a string by empty string yields empty strings

Hi. I noticed that when you split a string by an empty string, you get an empty string at the beginning and the end of the sequence (playground):

fn main() {
    let s = "abc";
    let v: Vec<_> = s.split("").collect();
    assert_eq!(v, Vec::from(["", "a", "b", "c", ""]))
}

Do you understand why this is so?

Technically it should panic, there's an infinite amount of empty strings at every position, after all. Instead, for whatever reason, it splits at every position, including the first and last position.

This specific behavior is called out in the docs: "When the empty string is used as a separator, it separates every character in the string, along with the beginning and end of the string."

While you might consider that there are an infinite number of empty strings at every position, to do so would be to permit overlapping matches, which isn't how split works.

4 Likes

In case this isn’t clear from the previous answers alone, let me illustrate this further. The logic is as follows: Find all unique occurrences of the "" (empty string) pattern in "abc", then split up the string around them. There’s an empty string at every position in the string, i.e.

  • before the a
  • between the a and b
  • between the b and c
  • after the c

which is everywhere indicated by an arrow in "↓a↓b↓c↓".

The behavior of "abc".split("") is simply the same as "↓a↓b↓c↓".split("↓") or "xaxbxcx".split("x").

5 Likes

Thank you all for your answers!