Recall that we talked about string literals being stored inside the binary. Now that we know about slices, we can properly understand string literals:
let s = "Hello, world!";
The type of s here is &str: it’s a slice pointing to that specific point of the binary. This is also why string literals are immutable; &str is an immutable reference.
How to understand these:
The type of s here is &str :
Why it is &str here?
it’s a slice pointing to that specific point of the binary.
What is the meaning here?
This is also why string literals are immutable; &str is an immutable reference.
Slices like [T] or str can be of any length; we say they are "unsized" or "dynamically sized types (DSTs)" or "don't implement Sized". For this reason, you almost always interact with them behind some sort of pointer: a &[T], &str, Arc<str>, and so on. Pointers to slices are "wide"[1] pointers that contain not only a pointer to the data in the usual sense, but also the length of the slice.
Without a wide pointer, you don't know the length, so that's why a literal "..." is a &str and not a str, say. It can't be a String because that requires a run-time allocation. (The core language doesn't even have heap allocation.)
The data is part of your compiled program. In this playground, select ASM instead of Run, and in the output you will see:
.L__unnamed_3:
.ascii "hello"
When your operating system loads your executable into memory, that data will be placed in some read-only section of memory (which your code can then read).