【问题标题】: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 无效

【问题讨论】:

    标签: rust


    【解决方案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 。整洁的谢谢。
    • 下划线告诉编译器推断类型。每个下划线只有一个有效类型,所以我们不需要拼写出来。
    猜你喜欢
    • 2020-07-20
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-23
    • 2020-02-10
    • 2018-10-24
    相关资源
    最近更新 更多