What is the syntax to match on a reference to an e

2019-01-14 06:36发布

It seems like every introductory document for Rust's enum types explains how to match on an enum object that you own, but what if you do not own the enum object and you just have a reference to it that you want to match against? I don't know what the syntax would be.

Here is some code where I attempt to match on a reference to an enum:

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);
}

The Rust Playground gives errors on the first two cases of the match when trying to compile it:

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`

How can I change that code to get it to compile? I tried adding ampersands in lots of different places without any luck. Is it even possible to match on a reference to an enum?

标签: rust
3条回答
神经病院院长
2楼-- · 2019-01-14 06:53

As of Rust 1.26, the idiomatic way is the way that you originally wrote it because match ergonomics have been improved:

use std::fmt;

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

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

fn main() {
    let p: Animal = Animal::Cat("whiskers".to_owned());
    println!("{}", p);
}
查看更多
你好瞎i
3楼-- · 2019-01-14 07:00

The idiomatic way would be

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

You can use _ instead of ref c to silence the "unused" warning.

查看更多
老娘就宠你
4楼-- · 2019-01-14 07:02

I figured it out thanks to helpful compiler messages:

match self {
    &Animal::Cat(ref c) => f.write_str("c"),
    &Animal::Dog => f.write_str("d"),
}
查看更多
登录 后发表回答