Standard Collections

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 a String into its underlying Vec<u8> unconditionally in $O(1)$ time.
  • String::from_utf8(vec) -> Result<String, FromUtf8Error>: Validates that vec: Vec<u8> contains valid UTF-8 ($O(n)$ scan) and wraps the existing heap allocation in a String without copying bytes. If validation fails, err.into_bytes() returns the original Vec<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