Skip to content

str::is_empty

str methods · Strings

Level: reference · for working programmers

One line: true when the string holds no bytes — the same test as len() == 0, written so the reader does not have to work out which comparison you meant.

pub const fn is_empty(&self) -> bool

Stable since 1.0.0. Usable in a const context.

There is nothing to it beyond self.len() == 0, and that is the point: is_empty() states the question, while len() == 0 states an implementation of it. Clippy's len_zero lint will rewrite the second into the first.

Empty is not blank. A string of three spaces is not empty, and this is the single most common bug in input handling — a form field the user tabbed through still arrives as " ". Test the trimmed value instead:

fn main() {
    let field = "   ";
    println!("{} {}", field.is_empty(), field.trim().is_empty());  // false true
}

Empty is also not "missing". If a value can legitimately be absent, that is Option<String>, and collapsing None and Some("") into one empty string throws away the difference between the user left it blank and we never asked.

Example

str_is_empty.rs in full — pasted here by tools/run_examples.py from the file CI compiles and runs.

fn main() {
    let cases = ["", " ", "   ", "\n", "a"];
    println!("{:<6} {:<8} {}", "input", "empty?", "trimmed empty?");
    for s in cases {
        // Debug ignores a width, so pad the formatted string, not the value.
        println!("{:<6} {:<8} {}", format!("{s:?}"), s.is_empty(), s.trim().is_empty());
    }

    // The whole implementation.
    let s = "";
    println!("{}", s.is_empty() == (s.len() == 0));

    // Empty is not missing: Option carries the difference is_empty cannot.
    let answers: [Option<&str>; 3] = [Some("yes"), Some(""), None];
    for a in answers {
        let verdict = match a {
            None => "never asked",
            Some(v) if v.trim().is_empty() => "asked, left blank",
            Some(_) => "answered",
        };
        println!("{a:?} -> {verdict}");
    }
}

Verified output of str_is_empty.rs — regenerated by tools/run_examples.py, never hand-typed.

input  empty?   trimmed empty?
""     true     true
" "    false    true
"   "  false    true
"\n"   false    true
"a"    false    false
true
Some("yes") -> answered
Some("") -> asked, left blank
None -> never asked

See also

  • str::len — what this is comparing against zero
  • str::trim — what to call first when the input is typed by a human
  • String::is_empty — the same test on the owned type

str::is_empty in the standard library ↗

Po polsku

W polszczyźnie jedno słowo „pusty” obsługuje dwa pojęcia, które angielski rozdziela na empty i blank — i dokładnie na tej szczelinie powstaje błąd opisany na tej stronie. is_empty() odpowiada wyłącznie na pytanie „zero bajtów?”, więc pole formularza, przez które użytkownik tylko przeskoczył tabulatorem, przychodzi jako " " i jest niepuste. Wydruk pokazuje to wprost: dla " " oraz "\n" pierwsza kolumna to false, a druga true. Przy danych wpisywanych przez człowieka pytaj więc o s.trim().is_empty(), nie o samo is_empty().

Druga różnica to „puste” kontra „brak” — znajoma każdemu, kto zderzył w SQL-u NULL z ''. Jeżeli wartości może w ogóle nie być, właściwym typem jest Option<String>; zwinięcie None i Some("") w jeden pusty łańcuch znaków bezpowrotnie kasuje informację, czy użytkownik zostawił pole puste, czy nikt go o nic nie zapytał — te trzy przypadki rozstrzyga match w przykładzie. Drobiazg na koniec: clippy i tak przepisze len() == 0 na is_empty() (lint len_zero), więc od razu pisz tę drugą formę.

Szukaj po polsku: pusty łańcuch znaków · walidacja pustego pola formularza · rust is_empty vs trim is_empty · rust clippy len_zero