如何在结构方法中与其他结构进行比较

时间:2019-07-10 19:25:41

标签: rust

我不确定为什么,但是我的方法不起作用,有没有办法将self与它的父结构进行比较?我添加了上下文数据结构。

#[derive(PartialEq, Copy, Clone, Debug)]
enum Suits {
    Hearts,
    Spades,
    Clubs,
    Diamonds,
}

#[derive(PartialEq, Copy, Clone, Debug)]
struct Card {
    card_num: u8,
    card_suit: Suits,
}



    fn match_card(&self, deck: &[Option<Card>]) -> bool {
        for i in deck.iter() {
            match i.unwrap() {
                self => {
                    println!("\nFound card in deck!\nCard found is {:#?}\n", i.unwrap());
                    return true;
                }
                _ => continue,
            }
        }
        false
    }

我得到:

`self` value is a keyword and may not be bound to variables or shadowed

2 个答案:

答案 0 :(得分:4)

match语句将提供的值与模式相匹配。将值与模式匹配与测试相等性不同。如果您要使用后者,请改用if语句。您可以在subsection on pattern syntax in the book中阅读模式。

仅包含一个标识符(例如x)的模式与提供的任何值匹配,并且该值被分配x。这意味着模式self不会将值与self的值进行比较,而是尝试将匹配表达式的值分配给self,这是不允许的,因为错误消息说明。

您的函数应该这样写:

fn match_card(&self, deck: &[Option<Card>]) -> bool {
    deck.iter().flatten().any(|card| card == self)
}

这假设PartialEq是为Card类型实现的,通常可以使用#[derive(PartialEq)]完成。

以上代码中的flatten()方法将每个Option<Card>视为嵌套的迭代器。如果选项为Option,则迭代None不会产生任何元素,否则,选项中的单个值将被包装。这意味着deck.iter().flatten()是一个迭代器,可对切片中的所有&Card项产生Some(_),而所有None项都将被跳过。

答案 1 :(得分:1)

假设Card实现了PartialEq,则可以使用match guard

fn match_card(&self, deck: &[Option<Card>]) -> bool {
    for i in deck.iter() {
        match i {
            Some(c) if c == self => {
                println!("\nFound card in deck!\nCard found is {:#?}\n", c);
                return true;
            }
            _ => continue,
        }
    }
    false
}

playground demo

我无法确定真正的代码是什么,但是如果您没有理由使用match,那么在这里使用简单的if测试就更合适了。