String::from() / to_string()
Rust has two string types: String (owned, mutable) and string slice &str (borrowed, immutable). You can create a String value using String::from() or to_string().
Syntax
// Ways to create a String.
let s1 = String::from("hello"); // Creates a String from a &str.
let s2 = "world".to_string(); // Using the to_string() method.
let s3 = String::new(); // Creates an empty String.
let s4 = "hello".to_owned(); // to_owned() also creates a String.
// &str (string slice) is a reference to a String or a string literal.
let literal: &str = "hello"; // A string literal has type &str.
let borrowed: &str = &s1; // A slice of a String via Deref coercion.
let slice: &str = &s1[0..3]; // References a portion of the string by range.
// Converting between String and &str.
let s: String = String::from("hello");
let r: &str = &s; // &String → &str (Deref coercion)
let s2: String = r.to_string(); // &str → String
Creation Methods
| Syntax | Description |
|---|---|
| String::from("text") | Creates a String from a &str. The most common approach. |
| "text".to_string() | Creates a String via the ToString trait. |
| "text".to_owned() | Creates a String via the ToOwned trait. |
| String::new() | Creates an empty String. |
| String::with_capacity(n) | Creates a String with at least n bytes of pre-allocated capacity. |
| format!("...") | Creates a formatted String. |
| "text" (literal) | A string literal of type &str (embedded in the program binary). |
| &s (&String to &str) | Usable as &str via Deref coercion on a String reference. |
Sample Code
fn print_str(s: &str) {
// Accepts a &str. A String can also be passed via Deref coercion from &String.
println!("String: {}", s);
}
fn main() {
// --- Creating Strings ---
let s1 = String::from("Hello, Rust!");
let s2 = "Hello, World!".to_string();
let s3 = String::new();
let s4 = String::with_capacity(50); // Pre-allocates 50 bytes of capacity.
println!("s1: {}", s1);
println!("s2: {}", s2);
println!("s3 (empty): '{}'", s3);
println!("s4 (empty, capacity 50): len={}, capacity={}", s4.len(), s4.capacity());
// --- &str literals ---
let literal: &str = "hello";
println!("literal: {}", literal);
// --- Converting between String and &str ---
let owned: String = "Rust".to_string();
let borrowed: &str = &owned; // &String → &str (automatic conversion)
let owned2: String = borrowed.to_string(); // &str → String
println!("owned: {}", owned);
println!("borrowed: {}", borrowed);
println!("owned2: {}", owned2);
// --- Passing strings to functions ---
// A function taking &str accepts both String and &str.
print_str("string literal");
print_str(&s1); // &String is automatically converted to &str.
// --- Slicing ---
let hello = &s1[0..5]; // "Hello" (byte-based range)
println!("slice: {}", hello);
// --- Creating a String with format! ---
let name = "Alice";
let age = 30;
let profile = format!("Name: {}, Age: {}", name, age);
println!("{}", profile);
// --- When to use String vs &str ---
// Need ownership of the string → use String
// Only need to read the string (no ownership needed) → use &str
}
Notes
Rust's String is a heap-allocated data structure that stores a UTF-8 byte sequence internally. &str, on the other hand, is a reference (slice) into that byte sequence. When accepting a string as a function parameter, it is idiomatic to use &str rather than &String, since &str accepts a wider range of types.
When slicing strings that contain multibyte characters such as Japanese, specifying a byte offset that does not fall on a character boundary will cause a panic. Use .chars() for character-level operations.
For concatenating and appending strings, see String::push_str() / push() / +. For length, emptiness checks, and searching, see String::len() / is_empty() / contains().
If you find any errors or copyright issues, please contact us.