How to Convert Between String and &str in Rust

You convert a `String` to `&str` using the `as_str()` method or by simply borrowing it, while converting `&str` to `String` requires calling the `to_string()` method or using `String::from()`.

You convert a String to &str using the as_str() method or by simply borrowing it, while converting &str to String requires calling the to_string() method or using String::from(). The first operation is zero-cost because it only creates a reference, whereas the second allocates new memory on the heap to own the data.

When you have an owned String and need to pass it to a function expecting &str, you can borrow it directly. Rust's coercion rules often handle this automatically, but as_str() makes the intent explicit and is useful when you need to ensure you are working with a slice.

fn main() {
    let owned_string = String::from("Hello, world!");
    
    // Convert String to &str
    let slice: &str = owned_string.as_str();
    // Or simply: let slice = &owned_string;
    
    println!("Slice: {}", slice);
}

Converting from &str to String is necessary when you need to own the data, such as storing it in a struct or returning it from a function. This operation clones the underlying bytes into a new String instance on the heap.

fn main() {
    let slice: &str = "Hello, world!";
    
    // Convert &str to String
    let owned_string: String = slice.to_string();
    // Alternatively: let owned_string = String::from(slice);
    
    println!("Owned: {}", owned_string);
}

A common pitfall occurs when you try to store a &str that points to a String created within the same scope. If the String is dropped, the &str becomes a dangling reference. To avoid this, ensure the String lives as long as or longer than the &str you derive from it. If you need to return a string from a function, always return String to guarantee ownership, or use &'static str if the data is a compile-time constant.

// Correct: Returns owned String
fn get_message() -> String {
    "Hello".to_string()
}

// Correct: Returns static reference
fn get_static_message() -> &'static str {
    "Hello"
}

// Incorrect: Returns reference to local variable (compilation error)
// fn get_bad_message() -> &str {
//     let s = String::from("Hello");
//     &s // Error: s does not live long enough
// }

In summary, use as_str() or implicit borrowing to get a view of a String without copying, and use to_string() when you need to take ownership of the data.