Hello Rustaceans,
In the rust programming language book, on string slices and string literal, it is said that
let s = "hello";
s
is a string literal, where the value of the string is hardcoded directly into the final executable, more specifically into the.text
section of our program. (Rust book)- 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. (Rust Book ch 4.3)
Now one beg the question, how does rustc
determine how to move value/data into that memory location associated with a string slice variable if it is marked as mutable?
Imagine you have the following code snippet:
fn main() {
let greeting: &'static str = "Hello there"; // string literal
println!("{greeting}");
println!("address of greeting {:p}", &greeting);
// greeting = "Hello there, earthlings"; // ILLEGAL since it's immutable
// is it still a string literal when it is mutable?
let mut s: &'static str = "hello"; // type is `&'static str`
println!("s = {s}");
println!("address of s {:p}", &s);
// does the compiler coerce the type be &str or String?
s = "Salut le monde!"; // is this heap-allocated or not? there is no `let` so not shadowing
println!("s after updating its value: {s}"); // Compiler will not complain
println!("address of s {:p}", &s);
// Why does the code above work? since a string literal is a reference.
// A string literal is a string slice that is statically allocated, meaning
// that it’s saved inside our compiled program, and exists for the entire
// duration it runs. (MIT Rust book)
let mut s1: &str = "mutable string slice";
println!("string slice s1 ={s1}");
s1 = "s1 value is updated here";
println!("string slice after update s1 ={s1}");
}
if you run this snippet say on Windows 11, x86 machine you can get an output similar to this
$ cargo run
Compiling tut-005_strings_2 v0.1.0 (Examples\tut-005_strings_2)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.42s
Running `target\debug\tut-005_strings_2.exe`
Hello there
address of greeting 0xc39b52f410
s = hello
address of s 0xc39b52f4c8
s after updating its value: Salut le monde!
address of s 0xc39b52f4c8
string slice s1 =mutable string slice
string slice after update s1 =s1 value is updated here
-
Why does this code run without any compiler issue?
-
is the variable
s
,s1
still consider a string literal in that example?-
if
s
is a literal, how come at run time, the value in the address binded tos
stay the same?- maybe the variable of type
&str
is an immutable reference, is that's why the address stays the same? How about the value to that address? Why does the value/the data content ins
ors1
is allowed to change? Does that mean that this string is no longer statically "allocated" into the binary anymore?
- maybe the variable of type
-
-
How are values moved in Rust?
Help, I'm confused.