为啥在 Rust 中将 const 引用直接转换为可变引用无效?

Posted

技术标签:

【中文标题】为啥在 Rust 中将 const 引用直接转换为可变引用无效?【英文标题】:Why is casting a const reference directly to a mutable reference invalid in Rust?为什么在 Rust 中将 const 引用直接转换为可变引用无效? 【发布时间】:2018-11-24 13:47:12 【问题描述】:

这段代码是正确的:

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 无效

【问题讨论】:

【参考方案1】:

“为什么”这个问题的肤浅答案就是这些只是 Rust 中 as 表达式的规则。引用自Nomicon:

强制转换是不可传递的,也就是说,即使e as U1 as U2 是有效的 表达式,e as U2 不一定如此。

使用as 运算符,您可以执行显式coercionscasts

直接从&u8*mut u8 既没有强制转换也没有强制转换。但是,从&T*const T 有一个指针弱化强制转换,还有一个强制转换 从一个指向大小类型的指针到任何其他类型。两者的组合会产生您问题中的表达式。

更深层次的问题是为什么语言是这样设计的。我实际上不知道,因为做出这些决定时我不在房间里,而且我在网上找不到理由。 Rust 通常会尝试非常明确地使用类型转换,以避免实际不打算进行的转换并保持规则简单。这些原则似乎也影响了这个特定的设计决策。

【讨论】:

这是我最终不得不做的事情,这是有道理的,但一开始看起来很傻... let ptr: *mut u8 = &op_create as *const control_operation as *const u8 as *mut u8 ; @stu 如果你想为阅读代码的人节省一些打字和一些不相关的噪音,你也应该可以使用&op_create as *const _ as *const _ as *mut u8 有趣,它不关心你强制或强制转换为什么类型,只是你正在转换为 const 与 mut 。整洁的谢谢。 下划线告诉编译器推断类型。每个下划线只有一个有效类型,所以我们不需要拼写出来。

以上是关于为啥在 Rust 中将 const 引用直接转换为可变引用无效?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在特殊成员函数中将 r 值绑定到 const 左值引用是非法的?

在rust-cpython中将Rust结构转换为PyObject

在 C++ 中将非 const 转换为 const

为啥非 const 引用必须用左值初始化?

在 Rust 中将二进制字符串转换为带有前导零的十六进制字符串

为啥在 Rust 中将字符串的第一个字母大写如此复杂?