На что ссылается &self в трейте Deref, реализованном во внутренней структуре?

Я нашел этот фрагмент кода в сообщении Reddit, который меня очень сбивает с толку.

//We'll recurse all we want, thank you very much!
#![allow(unconditional_recursion)]

use std::ops::Deref;

#[derive(Debug)]
struct Outer<T: Deref<Target = Outer<T>>> {
    inner: T,
}

impl<T: Deref<Target = Outer<T>>> Deref for Outer<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

#[derive(Debug)]
struct Inner {}

impl Deref for Inner {
    type Target = Outer<Inner>;

    fn deref(&self) -> &Self::Target {
        //Look at which struct we're implementing Deref for,
        //and then read the next line very carefully.
        &self.inner
    }
}

const I: Inner = Inner {};
const O: Outer<Inner> = Outer { inner: I };

fn main() {
    println!("{:?}", O.inner);
    //Could just keep adding asterisks forever!
    println!("{:?}", *O.inner);
    println!("{:?}", **O.inner);
    println!("{:?}", ***O.inner);

    println!("{:?}", O);
    //Could just keep adding asterisks forever!
    println!("{:?}", *O);
    println!("{:?}", **O);
    println!("{:?}", ***O);
}

Конкретно здесь:

impl Deref for Inner {
    type Target = Outer<Inner>;

    fn deref(&self) -> &Self::Target {
        //Look at which struct we're implementing Deref for,
        //and then read the next line very carefully.
        &self.inner
    }
}

Как функция возвращает ссылку на поле, принадлежащее другой структуре? Действительно ли &self относится здесь к Внешнему?

(Также этот код каждый раз вылетает из-за переполнения стека)

Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
0
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Действительно нет inner на Inner. Но перед тем, как сдаться, компилятор думает: «Погоди, а есть какая-нибудь Deref реализация для Inner?» и, конечно же, ответ есть! Мы пишем это прямо сейчас! Итак, что он возвращает? Outer<Inner>? Что ж, попробуй дерефовать и найти inner на Outer<Inner>! То есть &self.inner превращается в &<Self as Deref>::deref(&self).inner. Это автоопределение в действии.

Конечно, поскольку мы уже внутри <Inner as Deref>::deref(), мы вызываем его снова, рекурсивно... и снова... и снова... пока не взорвем стек. Если вы уберете #[allow(unconditional_recursion)] вверху, компилятор предупредит вас об этом (детская площадка):

warning: function cannot return without recursing
  --> src/main.rs:22:5
   |
22 |     fn deref(&self) -> &Self::Target {
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
...
25 |         &self.inner
   |          ---------- recursive call site
   |
   = note: `#[warn(unconditional_recursion)]` on by default
   = help: a `loop` may express intention better if this is on purpose

Но когда вы говорите #[allow(unconditional_recursion)], вы говорите компилятору: «Поверьте мне, я знаю, что делаю», поэтому он просто пожимает плечами и продолжает.

Большое спасибо, это просто ответы на мои вопросы!!!

饿羊吃狼 10.05.2022 19:36

Другие вопросы по теме