Отключить неявное приведение к разыменованию - PullRequest
0 голосов
/ 17 апреля 2020

Мой вопрос здесь вполне конкретен c. Я хочу отключить неявные разыменные приведения (скажем, потому что они мне не нравятся). В частности, я хочу, чтобы этот код не работал:

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

На мой взгляд, это довольно бессмысленный пример. Но он компилируется, потому что (я полагаю) &mut T приводит к T и, следовательно, утверждение y = &mut y является недопустимым.

Предполагая, что это правильно, как мне предотвратить Rust от делать это? Я пытался, например, использовать #[no_implicit_prelude], но без радости.

1 Ответ

1 голос
/ 17 апреля 2020

Код, который вы дали, на самом деле не использует автоматическую разыменование. Тип y равен &Box<i32>, а println работает, потому что форматирование Display для Box состоит в том, чтобы просто делегировать его реализацию Display.

Если я немного изменю ваш пример , мы можем включить автоматическую разыменование в игру:

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

Вы не можете отключить любые черты, которые реализованы для встроенных типов. Вы можете сделать свой собственный Box, который не реализует Deref:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...