Как сравнить & self в методе struct с другой структурой - PullRequest
0 голосов
/ 10 июля 2019

Я не уверен, почему, но мой метод не работает, есть ли способ сравнить себя с его родительской структурой? Я добавил структуры данных для контекста.

#[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 ]

4 голосов
/ 10 июля 2019

Оператор match сопоставляет предоставленное значение с шаблонами . Сопоставление значения с шаблоном отличается от проверки на равенство. Если последнее - то, что вы хотите сделать, используйте вместо этого оператор if. Вы можете прочитать о шаблонах в подразделе о синтаксисе шаблонов в книге .

Шаблон, состоящий только из идентификатора, скажем, 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 голос
/ 10 июля 2019

Предполагая, что Card реализует PartialEq, вы можете использовать охранник матча :

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
}

демо-площадка

Я не могу сказать, что такое настоящий код, но если у вас нет причин использовать match, простой тест if будет более уместным здесь.

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