str::len¶
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.
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.
See also¶
str::is_empty— the== 0test, spelled so it readsstr::chars— the other ruler over the same textString::len— identical —Stringderefs tostr, and this is the same countstr::is_char_boundary— whether a byte offset is a legal slice endpoint
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