String
Within the standard library's collection hierarchy, String is a specialized sequence collection that wraps a Vec<u8> with a UTF-8 validity invariant, bridging byte-buffer storage and character-oriented text operations.
How String Relates to Vec<T> in the Collection Hierarchy
String shares the exact same 24-byte stack layout (ptr, len, capacity) and geometric growth strategy as Vec<u8>, while restricting direct element indexing and mutation so no operation can ever leave invalid UTF-8 bytes in the buffer:
| Collection Aspect | Vec<u8> |
String |
|---|---|---|
| Stack representation | (ptr, len, capacity) (24 bytes) |
Vec<u8> (24 bytes) |
| Element invariant | Arbitrary u8 bytes (0x00..=0xFF) |
Valid UTF-8 sequences only |
Deref target (&Self -> &Target) |
&[u8] |
&str |
IntoIterator item (for x in c) |
u8 |
None directly — choose .chars() or .bytes() explicitly |
FromIterator / Extend inputs |
u8, &u8 |
char, &char, &str, String, Cow<'_, str> |
Direct index c[i] |
u8 at byte i |
Forbidden (E0277); range slicing &s[a..b] yields &str |
Zero-Cost Conversion Between String and Vec<u8>
Because a String literally wraps a Vec<u8>, converting between them transfers ownership of the heap pointer in $O(1)$ time without copying or reallocating the buffer:
s.into_bytes() -> Vec<u8>: Unwraps aStringinto its underlyingVec<u8>unconditionally in $O(1)$ time.String::from_utf8(vec) -> Result<String, FromUtf8Error>: Validates thatvec: Vec<u8>contains valid UTF-8 ($O(n)$ scan) and wraps the existing heap allocation in aStringwithout copying bytes. If validation fails,err.into_bytes()returns the originalVec<u8>unharmed.
fn main() {
let original = String::from("Rust 2024");
let ptr_before = original.as_ptr();
// 1. Convert String -> Vec<u8> with zero allocation:
let mut bytes: Vec<u8> = original.into_bytes();
bytes.extend_from_slice(b"!");
// 2. Convert Vec<u8> -> String with zero allocation:
let restored = String::from_utf8(bytes).unwrap();
let ptr_after = restored.as_ptr();
println!("Restored: '{restored}' (same buffer: {})", ptr_before == ptr_after);
}
Restored: 'Rust 2024!' (same buffer: true)
Collection Traits Implemented by String
Like Vec<T>, String implements the standard collection traits Default, Clone, Extend, FromIterator, Index<Range<usize>>, and Borrow<str>, allowing iterator pipelines to collect or extend characters and string slices directly into a String:
fn main() {
let words = ["collections", "and", "strings"];
// Collects `&str` items directly into a single `String`:
let banner: String = words.into_iter().collect::<Vec<_>>().join(" :: ");
let filtered: String = banner.chars().filter(|c| !c.is_whitespace()).collect();
println!("Banner: {banner}");
println!("Filtered: {filtered}");
}
Banner: collections :: and :: strings
Filtered: collections::and::strings