How to convert between String and str

You convert a `String` to a `&str` by borrowing it with `&` or `&s[..]`, while converting a `&str` to a `String` requires allocation using `.to_string()` or `String::from()`.

You convert a String to a &str by borrowing it with & or &s[..], while converting a &str to a String requires allocation using .to_string() or String::from(). The key distinction is that &str is a borrowed, zero-cost view of string data, whereas String owns its heap-allocated buffer and can be modified.

To get a &str from a String, you simply borrow the string. This is the most common pattern when passing string data to functions that accept &str to avoid unnecessary copying. You can use the reference operator & or slice syntax &s[..]; both produce the same result.

fn main() {
    let owned = String::from("Hello, Rust!");
    
    // Borrow the String to get &str (zero-cost)
    let borrowed: &str = &owned;
    // Alternatively: let borrowed: &str = &owned[..];
    
    println!("Borrowed: {}", borrowed);
    // owned is still usable here
}

Converting a &str to a String requires allocating new memory on the heap because the String must own the data. Use .to_string() for the most idiomatic approach, or String::from() if you prefer explicit construction. Both methods clone the underlying bytes.

fn main() {
    let borrowed: &str = "Hello, Rust!";
    
    // Allocate a new String from &str
    let owned: String = borrowed.to_string();
    // Alternatively: let owned = String::from(borrowed);
    
    println!("Owned: {}", owned);
    // borrowed is still usable here
}

When working with function arguments, prefer &str over String for parameters unless you specifically need to take ownership of the data. This allows your function to accept both String and &str arguments without forcing the caller to clone data.

// Accepts both &str and String (via automatic deref coercion)
fn greet(name: &str) {
    println!("Hello, {}!", name);
}

fn main() {
    let s = String::from("Alice");
    greet(&s);      // Passes &String, coerced to &str
    greet("Bob");   // Passes &str literal
}

Remember that String implements Deref<Target = str>, which enables automatic dereferencing. This means you can call &str methods directly on a String without explicit conversion, but you cannot mutate a &str because it is immutable by definition. If you need to modify the content, you must have a String or a mutable reference to one.