Skip to content

str::len

str methods · Strings

Level: reference · for working programmers

One line: The number of bytes in the UTF-8 encoding, not the number of characters — "héllo".len() is 6.

pub const fn len(&self) -> usize

Stable since 1.0.0. Usable in a const context.

len reads the length field that every &str already carries, so it is O(1) and never looks at the text. What it counts is the unit the text is stored in: UTF-8 bytes. ASCII makes the two readings agree, which is why the difference is usually discovered by a name with an accent in it rather than by a test.

There is no method that answers "how many characters", because the question has four honest answers — bytes, chars, UTF-16 code units, and what a reader would call a letter. Pick the one you mean:

you want write
bytes of storage s.len()
Unicode scalars s.chars().count()
a slice endpoint a byte offset from char_indices or find

chars().count() walks the whole string, so it is O(n) — the asymmetry is deliberate, and it is the clearest signal that len is not the character count.

The one place this reliably bites is a hand-rolled truncation. &s[..10] is ten bytes, and if byte 10 lands inside a character the program panics — see is_char_boundary and floor_char_boundary for the two ways out.

Example

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

fn main() {
    let ascii = "hello";
    let accented = "héllo";
    let emoji = "hi 👋";

    for s in [ascii, accented, emoji] {
        println!("{:<8} len={} chars={}", s, s.len(), s.chars().count());
    }

    // len() is the length of the *view*, not of whatever owns the bytes.
    let owner = String::from("hello world");
    let window = &owner[0..5];
    println!("owner {} / window {}", owner.len(), window.len());

    // It is a const fn, so a literal's length is known at compile time.
    const GREETING: &str = "hello";
    const N: usize = GREETING.len();
    println!("const len = {N}");
}

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

hello    len=5 chars=5
héllo    len=6 chars=5
hi 👋     len=7 chars=4
owner 11 / window 5
const len = 5

See also

str::len in the standard library ↗

Po polsku

len() liczy bajty, nie litery, a dla polskiego tekstu obie liczby rozjeżdżają się natychmiast: "Łódź".len() daje 7, podczas gdy "Łódź".chars().count() daje 4, bo Ł, ó i ź zajmują po dwa bajty. Jeśli masz za sobą czasy ISO-8859-2, CP1250 czy Mazovii, gdzie każda polska litera mieściła się w jednym bajcie, to właśnie z tym przyzwyczajeniem trzeba się tu rozstać. Sam odczyt nic nie kosztuje — len czyta gotowe pole długości, które każdy &str ze sobą nosi, i nigdy nie zagląda w treść.

Metody „ile znaków” celowo nie ma, bo uczciwe odpowiedzi są trzy: bajty (len), skalary Unicode (chars().count(), przechodzące cały łańcuch, więc O(n)) i to, co czytelnik nazwałby literą. Praktyczny wniosek jest jeden: przycięcie w rodzaju &s[..10] odmierza dziesięć bajtów i przy polskim tekście chętnie trafi w środek znaku, co kończy się paniką. Indeks do cięcia bierz z char_indices albo z find, ewentualnie napraw go przez floor_char_boundary.

Szukaj po polsku: długość łańcucha znaków w bajtach · liczba znaków a liczba bajtów · rust str len vs chars count · rust string length utf-8