Как я могу проверить, являются ли обе переменные одними? - PullRequest
3 голосов
/ 07 апреля 2020

Я запутался в ключевом слове Some(T).

Я хочу проверить наличие двух переменных, если определено значение (не None). Если это так, значение этих переменных обрабатывается.

Я знаю шаблон match, который работает следующим образом:

match value {
    Some(val) => println!("{}", val),
    None => return false,
}

Если я использую этот шаблон, он получит очень грязно:

match param {
    Some(par) => {
        match value {
            Some(val) => {
                //process
            },

            None => return false,
        }
    },

    None => return false,
}

Это не может быть правильным решением.

Это возможность спросить, если параметр и значение is_some() Это повлияет на такой код:

if param.is_some() && value.is_some() {
    //process
}

Но если я так делаю, мне всегда нужно развернуть param и value, чтобы получить доступ к значениям.

Я думал о чем-то подобном, чтобы избежать этого. Но этот код не работает:

if param == Some(par) && value == Some(val) {
    //process
}

Идея состоит в том, что значения доступны par и val, как в версии match.

Есть ли любое решение сделать что-то вроде этого?

Ответы [ 3 ]

8 голосов
/ 07 апреля 2020

Если у меня есть несколько Option значений для сопоставления, я сопоставляю по кортежу значений:

enum Color {
    Red,
    Blue,
    Green,
}

fn foo(a: Option<Color>, b: Option<i32>) {
    match (a, b) {
        (Some(Color::Blue), Some(n)) if n > 10 => println!("Blue large number"),
        (Some(Color::Red), _) => println!("Red number"),
        _ => (),
    }
}

fn main() {
    foo(Some(Color::Blue), None);
    foo(Some(Color::Blue), Some(20));
}         

Это позволяет мне сопоставлять интересные комбинации и отбрасывать остальные (или возвращать false, если это то, что вы хотите сделать).

4 голосов
/ 07 апреля 2020

Если ваша функция обрабатывает несколько Option значений и хотела бы отменить их, если они не Some, ваша функция может вернуть Option сама:

fn foo(param: Option<usize>, value: Option<usize>) -> Option<usize> {
    let result = param? + value?;
    Some(result)
}

Это будет закоротите функцию, если в param или value.

хранится значение None. Прочтите книгу для получения дополнительной информации об операторе ?.

Если ваша функция не может вернуть Option, вы все равно можете избежать деструктурирования, используя if let или match:

let x = if let (Some(p), Some(v)) = (param, value) {
    p + v
} else {
    return 0;
}
let x = match (param, value) {
    (Some(p), Some(v)) => p + v,
    (Some(p), _) => p,
    (_, Some(v) => v,
    _ => return 0,
}

1 голос
/ 07 апреля 2020

Есть еще пара альтернатив, которых еще нет в списке:

Если вы хотите использовать экспериментальные функции (и, следовательно, ночной компилятор), вы можете использовать блок try в качестве альтернативы извлечения функции.

#![feature(try_blocks)]

fn main() {
    let par: Option<f32> = Some(1.0f32);
    let value: Option<f32> = Some(2.0f32);

    let x: Option<f32> = try { par? + value? };

    println!("{:?}", x);
}

Другой альтернативой является использование map, которое применяется, только если значение не равно None

let x: Option<f32> = par.map(|p| value.map(|v| p + v));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...