#258 Jul 14, 2026

258. split_whitespace — Split on Runs, Not on Every Single Space

split(' ') hands you empty strings for every doubled space — and silently ignores tabs. split_whitespace is what you actually meant.

The trap

User input is messy: leading spaces, double spaces, a stray tab. split(' ') takes all of that literally:

1
2
3
4
5
6
7
let line = "  alpha\tbeta   gamma ";

let naive: Vec<&str> = line.split(' ').collect();
assert_eq!(
    naive,
    ["", "", "alpha\tbeta", "", "", "gamma", ""]
);

Two bugs in one line: every consecutive-space pair produces an empty string, and "alpha\tbeta" sails through as a single “word” because a tab isn’t a space.

The fix

split_whitespace splits on runs of any whitespace and never yields empty strings:

1
2
let words: Vec<&str> = line.split_whitespace().collect();
assert_eq!(words, ["alpha", "beta", "gamma"]);

Leading and trailing whitespace disappear too — no trim() needed first.

Unicode-aware, with an ASCII fast path

“Whitespace” here means the Unicode White_Space property, so a non-breaking space (\u{00A0}) splits words just like a regular one:

1
2
3
let fancy = "alpha\u{00A0}beta";
let words: Vec<&str> = fancy.split_whitespace().collect();
assert_eq!(words, ["alpha", "beta"]);

If your input is guaranteed ASCII (log files, protocol lines), split_ascii_whitespace does the same thing with a cheaper per-byte check — same no-empty-strings guarantee:

1
2
3
let words: Vec<&str> =
    " 42  7\t9 ".split_ascii_whitespace().collect();
assert_eq!(words, ["42", "7", "9"]);

Keep split(' ') for formats where empty fields are meaningful (CSV-like, fixed positions). For “give me the words”, it’s split_whitespace every time.

← Previous 257. VecDeque::rotate_left — Where the Ring Buffer Finally Pays Rent Next → 259. str::lines — Split Into Lines Without Dragging \r Along