Подтвердить что ты не робот

Соответствие ссылки на перечисление

Кажется, что каждый вводный документ для Rust перечисляет типы объясняет, как match для объекта перечисления, который у вас есть. Но что, если вы не являетесь владельцем объекта перечисления, и у вас есть только ссылка на него, с которой вы хотите сопоставить? Я не знаю, что такое синтаксис.

Вот некоторый код, где я пытаюсь сопоставить ссылку на перечисление:

use std::fmt;
use std::io::prelude::*;

pub enum Animal {
    Cat(String),
    Dog,
}

impl fmt::Display for Animal {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Animal::Cat(c) => f.write_str("c"),
            Animal::Dog => f.write_str("d"),
        }
    }
}

fn main() {
    let p: Animal = Animal::Cat("whiskers".to_owned());
    println!("{}", p);
}

Rust Playground дает ошибки в первых двух случаях совпадения при попытке скомпилировать его:

error[E0308]: mismatched types
  --> src/main.rs:12:13
   |
12 |             Animal::Cat(c) => f.write_str("c"),
   |             ^^^^^^^^^^^^^^ expected &Animal, found enum `Animal`
   |
   = note: expected type `&Animal`
   = note:    found type `Animal`

error[E0308]: mismatched types
  --> src/main.rs:13:13
   |
13 |             Animal::Dog => f.write_str("d"),
   |             ^^^^^^^^^^^ expected &Animal, found enum `Animal`
   |
   = note: expected type `&Animal`
   = note:    found type `Animal`

Как я могу изменить этот код для его компиляции? Я пробовал добавлять амперсанды в самых разных местах без всякой удачи. Можно ли даже сопоставить ссылку на перечисление?

4b9b3361

Ответ 1

Идиоматическим способом было бы

match *self {
    Animal::Cat(ref c) => f.write_str("c"),
    Animal::Dog => f.write_str("d"),
}

Вы можете использовать _ вместо ref c, чтобы отключить "неиспользуемое" предупреждение.

Ответ 2

Я понял это благодаря полезным сообщениям компилятора:

match self {
    &Animal::Cat(ref c) => f.write_str("c"),
    &Animal::Dog => f.write_str("d"),
}