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

3z6pesqy  于 2023-03-02  发布在  其他
关注(0)|答案(1)|浏览(188)

我正在阅读《铁 rust 》这本书来学习铁 rust ,目前正在学习所有权。它提到:
我们已经见过字符串常量,其中字符串值被硬编码到我们的程序中,字符串常量很方便,但它们并不适合我们可能想要使用文本的每一种情况,一个原因是它们是不可变的。
下面的代码运行起来没有任何问题。这里我改变了a的值,如果不变的字符串可以被改变,那么这里说明的问题是什么?

fn main() {
   let mut a = "Hello";
   println!("{}", a);
   a = " World";
   println!("{}", a);
}
bcs8qyzn

bcs8qyzn1#

rust编译器生成的可执行二进制文件在只读数据段rodata中包含字符串常量"Hello"和"World"。

$ cargo build --release
$ readelf -x .rodata target/release/demo | grep Hello
  0x0003c000 48656c6c 6f000000 0a576f72 6c640000 Hello....World..

因为这些文字被放置在一个不可变的节中,所以操作系统禁止修改它们。
x一个一个一个一个x一个一个二个x
但是,* 变量 * a的类型是&str,所以是一个指向字符串切片的指针,它存在于堆栈中,因此,a首先指向地址"Hello",然后指向地址"World"是完全有效的。

    • 编辑**:有关unsafe数据块的信息

我们希望向a指向的地址写入一些内容,以表明它确实存储在只读段中。
a被声明为mut a: &str,这意味着变量是可变的,但数据(字符串文字)是不可变的(与mut a: &mut str相反),因此,编译器阻止我们使用a.as_mut_ptr()来获取指向底层字节的可变(又称可写)指针。😉️). Thus, the compiler prevents us from using a.as_mut_ptr() to get a mutable (aka writable) pointer to the underlying bytes.
相反,我们要做一个小把戏:使用a.as_ptr()并将返回的const *u8强制转换为mut *u8。最后,写入指针需要unsafe块,因为您可能会违反Rust的内存安全,这可能会导致不好的事情发生,如上面所示的分段错误。

相关问题