What's the difference? - String::from() vs "literal"


Hi! I read the documentation, but did not understand what the difference between:

let x = String::from("Hi");


let x = "Hi";


Please quote here the documentation section you don’t understand.


The String Type


That’s a rather long section:

The String Type

To illustrate the rules of ownership, we need a data type that is more complex than the ones we covered in Chapter 3. The types covered in the “Data Types” section are all stored on the stack and popped off the stack when their scope is over, but we want to look at data that is stored on the heap and explore how Rust knows when to clean up that data.

We’ll use String as the example here and concentrate on the parts of String that relate to ownership. These aspects also apply to other complex data types provided by the standard library and that you create. We’ll discuss String in more depth in Chapter 8.

We’ve already seen string literals, where a string value is hardcoded into our program. String literals are convenient, but they aren’t always suitable for every situation in which you want to use text. One reason is that they’re immutable. Another is that not every string value can be known when we write our code: for example, what if we want to take user input and store it? For these situations, Rust has a second string type, String. This type is allocated on the heap and as such is able to store an amount of text that is unknown to us at compile time. You can create a String from a string literal using the from function, like so:

let s = String::from(“hello”);

The double colon (::slight_smile: is an operator that allows us to namespace this particular from function under the String type rather than using some sort of name like string_from. We’ll discuss this syntax more in the “Method Syntax” section of Chapter 5 and when we talk about namespacing with modules in Chapter 7.

This kind of string can be mutated:

let mut s = String::from(“hello”);

s.push_str(", world!"); // push_str() appends a literal to a String

println!("{}", s); // This will print hello, world!

So, what’s the difference here? Why can String be mutated but literals cannot? The difference is how these two types deal with memory.

Do you understand nothing in that whole section? Or do you understand some parts of it?


The difference boils down to Rust’s type inference.

// owned String, heap allocated
let x = String::from("Hi");

//  reference to string literal hardcoded in binary, 'static &str
let x = "Hi";

There is a lot of ergonomics talking going around about this theme, since the different types of string are not immediately obvious to newcomers.


I realized that the String type might change and save the text.