Strings and Text Processing
bytes()
The .bytes() method on str returns a std::str::Bytes<'_> iterator that yields each raw UTF-8 byte (u8) of the string by value, while .as_bytes() returns the underlying byte slice &[u8] directly.
Signatures and Traits
pub fn bytes(&self) -> std::str::Bytes<'_>
// where Bytes<'_>: Iterator<Item = u8> + DoubleEndedIterator + ExactSizeIterator + FusedIterator
pub const fn as_bytes(&self) -> &[u8]
Unlike .chars(), Bytes<'_> implements ExactSizeIterator because every item is a single u8 byte and the total byte length s.len() is known in $O(1)$ time.
fn main() {
let text = "Aé";
let raw_bytes: Vec<u8> = text.bytes().collect();
println!("Bytes of \"{text}\" (len={}): {raw_bytes:#04X?}", text.bytes().len());
println!("as_bytes() slice: {:#04X?}", text.as_bytes());
}
Bytes of "Aé" (len=3): [
0x41,
0xC3,
0xA9,
]
as_bytes() slice: [0x41, 0xC3, 0xA9]
Fast ASCII Scanning and Checksums with .bytes() and .as_bytes()
Because UTF-8 guarantees that an ASCII byte (0x00..=0x7F) can never appear as a leading or continuation byte of a multi-byte Unicode character (0x80..=0xFF), searching for ASCII delimiters (b':', b',', b'\n') or computing byte-level checksums via .bytes() or .as_bytes() is 100% UTF-8-safe and avoids UTF-8 code-point decoding overhead:
fn count_ascii_delimiters(csv_line: &str) -> (usize, u32) {
let commas = csv_line.bytes().filter(|&b| b == b',').count();
let checksum: u32 = csv_line.bytes().map(u32::from).sum();
(commas, checksum)
}
fn main() {
let row = "id,নাম,score";
let (commas, checksum) = count_ascii_delimiters(row);
println!("Commas: {commas}, byte checksum: {checksum}");
}
Commas: 2, byte checksum: 2348
.bytes() vs. .as_bytes()
| Method | Return Type | Best Used When... |
|---|---|---|
s.bytes() |
std::str::Bytes<'_> (Item = u8 by value) |
Iterating over u8 values directly without .copied() |
s.as_bytes() |
&[u8] (contiguous byte slice) |
Indexing s.as_bytes()[i] in $O(1)$, passing to Write::write_all, or using slice methods like .chunks() and .windows() |