Skip to content

str::bytes

str methods · Strings

Level: reference · for working programmers

One line: An iterator over the UTF-8 bytes, yielding u8 — the streaming form of as_bytes.

pub fn bytes(&self) -> Bytes<'_>

Stable since 1.0.0.

bytes() and as_bytes() expose the same data. Take the slice when you want to index, slice or pass it on; take the iterator when you want to chain adaptors, because Bytes is ExactSizeIterator and DoubleEndedIterator and composes with the rest of the iterator toolkit.

fn main() {
    let s = "hello";
    println!("{}", s.bytes().filter(|b| *b == b'l').count());  // 2
}

It yields bytes, so on non-ASCII text the count is not the character count and no single item is a character. chars is the iterator that yields characters; char_indices is the one that yields characters with the byte offsets you can slice at.

A byte iterator is the right tool for a checksum, a byte-level parser, or any scan whose alphabet is ASCII — where b'0'..=b'9' style comparisons are both correct and faster than decoding.

Example

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

fn main() {
    let s = "héllo";

    println!("{:?}", s.bytes().collect::<Vec<u8>>());
    println!("bytes={} chars={}", s.bytes().count(), s.chars().count());

    // ExactSizeIterator: the length is known without walking.
    println!("len hint = {}", s.bytes().len());

    // DoubleEndedIterator: same bytes, from the back.
    println!("{:?}", s.bytes().rev().take(3).collect::<Vec<u8>>());

    // A checksum — a job where bytes really are the unit.
    let sum: u32 = "hello".bytes().map(u32::from).sum();
    println!("sum = {sum}");

    // ASCII classification without decoding.
    let digits = "a1b2c3".bytes().filter(u8::is_ascii_digit).count();
    println!("{digits} ascii digits");
}

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

[104, 195, 169, 108, 108, 111]
bytes=6 chars=5
len hint = 6
[111, 108, 108]
sum = 532
3 ascii digits

See also

str::bytes in the standard library ↗

Po polsku

Dla polskiego tekstu różnica między bytes() a chars() nie jest ciekawostką, tylko codziennością: w UTF-8 każde ą, ć, ę, ł, ń, ó, ś, ź, ż zajmuje dwa bajty, więc "żółw".bytes().count() daje 7, a "żółw".chars().count() — 4. bytes() to strumieniowa wersja as_bytes(): te same dane, tylko jako iterator, więc weź wycinek, kiedy chcesz indeksować albo przekazać go dalej, a iterator, kiedy chcesz doczepić filter, rev czy sum. Bajty są właściwą jednostką do sumy kontrolnej i do skanowania czystego ASCII (b'0'..=b'9' porównuje się szybciej, niż dekoduje znaki) — do liczenia liter w polskim tekście nie nadają się nigdy.

Szukaj po polsku: polskie znaki w UTF-8 · bajty a znaki · iterator po bajtach · rust str bytes vs chars · rust utf-8 byte length