rust - 禁用隐式Deref强制

标签 rust

我的问题在这里很具体。我想禁用隐式deref强制(可以说是因为我不喜欢它们)。更具体地说,我希望此代码失败:

fn main() {
    let x = Box::new(0);
    let mut y = &x;
    y = &mut y;
    println!("GOT {}",*y);
}

在我看来,这是一个很荒谬的例子。但是,它之所以编译是因为(我认为)&mut T强制转换为T,因此y = &mut y语句是nop。

假设这是正确的,如何防止Rust这样做呢?例如,我尝试使用#[no_implicit_prelude],但没有任何乐趣。

最佳答案

您提供的代码实际上并未使用任何自动引用。 y的类型是&Box<i32>,而println可以工作,因为DisplayBox格式仅是委派给其内容Display实现。

如果我稍微更改您的示例,我们可以发挥自动取消引用的作用:

fn main() {
    let x = Box::new(0);
    let mut y: &i32 = &x; // <-- Deref impl is used here
    y = &mut y;
    println!("GOT {}", y);
}

您不能禁用为内置类型实现的任何特征。您可以创建自己的不实现BoxDeref:
use std::{boxed, fmt};

struct Box<T>(boxed::Box<T>);

impl<T> Box<T> {
    pub fn new(value: T) -> Self {
        Self(boxed::Box::new(value))
    }
}

impl<T: fmt::Display> fmt::Display for Box<T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.0)
    }
}

自动取消引用不起作用:
fn main() {
    let x = Box::new(0);
    let mut y: &i32 = &x; // <-- Error:  expected `i32`, found struct `Box`
    y = &mut y;
    println!("GOT {}", y);
}

但是您仍然可以打印包装盒本身:
fn main() {
    let x = Box::new(0);
    let mut y = &x; 
    y = &mut y;
    println!("GOT {}", y); // y: &Box<i32>
}

我不确定为什么您会这么做。您将不得不重新实现Box功能的很多才能使其普遍有用,并且完全不清楚没有Deref impl有什么好处。

关于rust - 禁用隐式Deref强制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61264079/

相关文章:

rust - 获取每行输入第一个单词的迭代器的简单实现

windows - Windows 上的 Rust 回溯?

json - 镍.rs : Receiving JSON data using HTTP POST request - rust keyword clash + fail on JSON null values

python - 为什么在使用 cdecl Rust 函数和 Python 的 Ctypes 传递指向切片的指针时会出现调用约定不匹配?

generics - 用泛型全面实现特征

rust - 找不到 `rayon` 的箱子

rust - 如何静态链接到现有的rlib?

rust - 为什么不能在结构定义中省略生命周期?

rust - 如何在 Serum Anchor 中签署代币交易

rust - 在 Rust 中返回新字符串的正确方法