Как сопоставление с образцом Rust определяет, будет ли связанная переменная ссылкой или значением? - PullRequest
0 голосов
/ 09 июня 2019
use crate::List::{Cons, Nil};

#[derive(Debug)]
struct Foo {}

#[derive(Debug)]
enum List {
    Cons(i32, Foo),
    Nil,
}

impl List {
    fn tail(&self) -> Option<&Foo> {
        match self {
            Cons(_, item) => Some(item), // why `item` is of type `&Foo`?
            Nil => None,
        }
    }
}

Как указано в комментарии, почему item имеет тип &Foo? Какое правило гласит, что item будет иметь тип &Foo, а не Foo?

Я понимаю, что для элемента не имеет смысла быть Foo; &self говорит, что self является ссылкой, поэтому нет смысла перемещать значение из ссылки, но есть ли какие-либо спецификации, которые четко определяют правила?

1 Ответ

6 голосов
/ 09 июня 2019

RFC 2005 (он же соответствует эргономике ) ввел правило.

До внесения изменений было 2 способа написать это match.

  1. Совпадение по self и префикс каждого шаблона с & для «деструктурирования» ссылки.

    fn tail(&self) -> Option<&Foo> {
        match self {
            &Cons(_, ref item) => Some(item),
            &Nil => None,
        }
    }
    
  2. Совпадение по *self и не ставьте перед каждым шаблоном префикс & (поскольку *self не является ссылкой).

    fn tail(&self) -> Option<&Foo> {
        match *self {
            Cons(_, ref item) => Some(item),
            Nil => None,
        }
    }
    

Тем не менее, в обоих случаях нам нужно написать ref item, в противном случае мы получим error[E0507]: cannot move out of borrowed content.

Однако в написанном match сопоставляемое выражение является ссылкой (тип &List), но шаблоны не являются эталонными (как в 1. выше).Вот тут-то и возникает эргономика соответствия: правило гласит, что когда ссылка сопоставляется с нереференсным шаблоном, привязки внутри этого шаблона связываются не по значению, а по ссылке (т. Е. Как если бы они имели префикс ref).

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