字符串文字是不可变的吗?

Ica*_*ode 4 immutability string-literals rust

我正在阅读 Rust 书来学习 Rust,目前正在学习所有权。它提到:

\n
\n

我们\xe2\x80\x99已经看到了字符串文字,其中字符串值被硬编码到我们的程序中。字符串文字很方便,但它们\xe2\x80\x99t\n适合我们可能想要使用文本的每种情况。原因之一是它们\xe2\x80\x99 是不可变的。

\n
\n

下面的代码运行没有任何问题。这里我改变了 的值a,如果不可变字符串可以改变什么\xe2\x80\x99s那里指出的问题?

\n
fn main() {\n   let mut a = "Hello";\n   println!("{}", a);\n   a = " World";\n   println!("{}", a);\n}\n
Run Code Online (Sandbox Code Playgroud)\n

lin*_*kmr 6

rust 编译器生成的可执行二进制文件在只读数据部分包含字符串“Hello”和“World” rodata

\n
$ cargo build --release\n$ readelf -x .rodata target/release/demo | grep Hello\n  0x0003c000 48656c6c 6f000000 0a576f72 6c640000 Hello....World..\n
Run Code Online (Sandbox Code Playgroud)\n

由于这些文字被放置在不可变的部分中,因此操作系统禁止修改它们。

\n
fn main() {\n    let mut a: &\'static str = "Hello";\n    println!("{}", a);\n\n    unsafe { (a.as_ptr() as *mut u8).write(42) };\n    println!("{}", a);\n}\n
Run Code Online (Sandbox Code Playgroud)\n
$ cargo run\nHello\nSegmentation fault\n
Run Code Online (Sandbox Code Playgroud)\n

但是,该变量 a的类型为&str,因此是一个指向字符串切片的指针,并且它位于堆栈中。a因此,首先指向“Hello”的地址,然后指向“World”的地址是完全有效的。

\n
\n

编辑:有关该unsafe块的信息

\n

我们想要向 wherea指向的地址写入一些内容,以表明它确实存储在只读部分中。

\n

a被声明为mut a: &str,意味着变量是可变的,但数据(字符串文字)是不可变的(与 \xef\xb8\x8f 相比mut a: &mut str)。\n因此,编译器阻止我们使用a.as_mut_ptr()来获取可变(又名可写)指针底层字节。

\n

相反,我们必须做一些小技巧:使用a.as_ptr()返回的并将其转换const *u8mut *u8. 最后,写入指针需要unsafe块,因为您可能会违反 Rust 的内存安全,这可能会导致不好的事情发生,如上面所示的分段错误。

\n