这段代码是正确的:
fn f() {
let mut x = 11;
b(&x as *const u8 as *mut u8);
}
fn b(x: *mut u8) {}
为什么b(&x as *const u8 as *mut u8)
有效而b(&x as *mut u8)
无效?编译器抱怨:
错误[E0606]:将
&u8
强制转换为*mut u8
答案 0 :(得分:2)
对“为什么”问题的肤浅回答。就是这些仅仅是Rust中as
表达式的规则。引用Nomicon:
投射不是传递性的,也就是说,即使
e as U1 as U2
是有效的 表达式,e as U2
不一定是这样。
使用as
运算符,您可以执行显式coercions或casts。
直接从&u8
到*mut u8
既没有强制性,也没有强制性。但是,从&T
到*const T
的指针削弱强制力和从指向大小类型的指针的 cast 到任何其他类型。两者的结合会在您的问题中表达您的观点。
更深层的问题是,为什么要用这种方式设计语言。我实际上不知道,因为做出这些决定时我不在房间里,而且我也找不到网上的理由。通常,Rust会尝试对类型强制转换非常明确,以免进行非实际的转换并简化规则。这些原理似乎也影响了这个特定的设计决策。