我正在将结构体的字段转换为*mut
指针,因此我将该结构体的引用声明为可变的。但是,我开始收到警告,说明mut
修饰符不是必需的。这对我来说很奇怪,我显然正在进行修改操作,但声明为mut
是不必要的?这导致我想到了这个最小示例:
struct NonMut {
bytes: [u8; 5]
}
impl NonMut {
pub fn get_bytes(&self) -> &[u8] {
&self.bytes
}
}
fn potentially_mutate(ptr: *mut u8) {
unsafe { *ptr = 0 }
}
fn why(x: &NonMut) {
let ptr = x.get_bytes().as_ptr() as *mut u8;
potentially_mutate(ptr);
}
fn main() {
let x = NonMut { bytes: [1, 2, 3, 4, 5] };
println!("{}", x.get_bytes()[0]);
why(&x);
println!("{}", x.get_bytes()[0]);
}
1
0
显然,解引用指针需要使用不安全代码,但对于刚开始编写自己的应用程序并决定调用why
(可能在一个外部crate中定义) 的人来说,这种行为似乎完全出乎意料。你传递了一个明显是不可变的引用,借贷检查器标记你的代码正确,但在底层,为该结构创建了一个可变引用。这可能会导致多个生存的可变引用被创建到NonMut
,而why
的用户却无法知道。
这种行为是否符合预期?难道将*mut
强制转换为操作数需要首先是mut
吗?没有必要这样做的充分理由吗?
NonMut
的本地mut变量,并使用它来获取mut*并通过该变量进行突变,则会出现警告。 - V0ldek