Rust中&str是指向二进制硬编码内容的指针,为何可声明为mut运行时修改?
Rust 字符串类型疑问解答
核心概念澄清
首先补全你对三种字符串类型的认知偏差:
str:Rust原生的不可变字符串切片类型,属于动态大小类型(DST),编译期无法确定长度,因此无法直接存储在栈上。它的存储位置不局限于二进制文件的只读数据段,也可以指向String在堆上申请的内存区域。&str:对str的不可变胖指针引用,栈上存储两份信息:指向str起始位置的指针、切片长度,本身没有底层数据的所有权,默认不允许修改指向的str内容。String: Rust标准库提供的拥有所有权的可变字符串类型,栈上存储指针、长度、容量,指针指向堆上的可变字符串数据,运行时可动态调整容量。
代码不报错的原因
你产生疑问的核心是混淆了引用变量本身的可变性和引用指向数据的可变性:
let mut s: &str = "foo"; s = "foobar";
这里mut修饰的是变量s本身,代表s这个存储在栈上的胖指针可以被重新赋值,指向其他的str地址。整个过程完全没有修改最初的"foo"静态字符串的内容,只是改变了s本身的指向,因此完全符合Rust的安全规则,不会触发编译错误。
如果你尝试修改s指向的str内容,比如执行s[0] = 'a',编译器会直接抛出错误,因为&str本身是不可变引用,没有权限修改指向的底层数据。
对比验证示例
如果去掉变量s的mut修饰,重新赋值就会报错:
let s: &str = "foo"; s = "foobar"; // 编译错误:无法对不可变变量`s`二次赋值
内容的提问来源于stack exchange,提问作者Jayson Meribe
相关产品推荐
相关产品推荐

