if let

В некоторых случаях использование match выглядит неуклюже. Например:

#![allow(unused)]

fn main() {

// Создаём переменную `optional` типа `Option`

let optional = Some(7);


match optional {

Some(i) => {

println!("Это очень большая строка и `{:?}`", i);

// ^ Нужно 2 отступа только для того, чтобы извлечь `i`

},

_ => {},

// ^ Обязателен, так как `match` исчерпывающий. Не выглядит ли это

// как потерянное пространство?

};


}

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

fn main() {

// Все переменные типа `Option`

let number = Some(7);

let letter: Option = None;

let emoticon: Option = None;

// Конструкция `if let` читает, как: "Если `let` деструктуризирует `number` в

// `Some(i)`, выполнить блок (`{}`).

if let Some(i) = number {

println!("Соответствует {:?}!", i);

}

// Если нужно указать, что делать, в случае ошибки, можно добавить else:

if let Some(i) = letter {

println!("Соответствует {:?}!", i);

} else {

// Ошибка деструктуризации. Переходим к обработке ошибки.

println!("Не соответствует числу. Давайте попробуем строку!");

}

// Добавляем ещё одну ситуацию несоответствия образцу.

let i_like_letters = false;

if let Some(i) = emoticon {

println!("Соответствует {:?}!", i);

// Оцените условие `else if`, чтобы увидеть,

// должна ли быть альтернативная ветка отказа:

} else if i_like_letters {

println!("Не соответствует числу. Давайте попробуем строку!");

} else {

// Рассматриваем ложное условие. Эта ветвь по умолчанию:

println!("Мне не нравится сравнивать строки. Давайте возьмём смайлик :)!");

}

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Точно так же, if let может быть использован для сравнения любого значения перечисления:

// Наш пример перечисления

enum Foo {

Bar,

Baz,

Qux(u32)

}

fn main() {

// Создание переменных примера

let a = Foo::Bar;

let b = Foo::Baz;

let c = Foo::Qux(100);

// Переменная `a` соответствует `Foo::Bar`

if let Foo::Bar = a {

println!("a = Foo::Bar");

}

// Переменная `b` не соответствует `Foo::Bar`.

// Поэтому ничего не выведется на экран

if let Foo::Bar = b {

println!("b = Foo::Bar");

}

// Переменная `c` соответствует `Foo::Qux`, которая имеет значение

// аналогичное `Some()` как в предыдущем примере:

if let Foo::Qux(value) = c {

println!("c ={}", value);

}

// С `if let` также работает и привязка

if let Foo::Qux(value @ 100) = c {

println!("c = 100");

}

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Другое преимущество if let в том, что он позволяет сопоставлять нам не параметризованные варианты перечисления. Это возможно даже если для перечисления не реализован и не выведен типаж PartialEq. В некоторых случаях, if Foo::Bar == a не скомпилируется, потому что экземпляры перечисления не могут быть равны. Однако, с if let всё будет работать.

Хотите вызов? Исправьте следующий пример с использованием if let :

// Для это перечисление намеренно не добавлен #[derive(PartialEq)],

// и мы не реализовывали для него PartialEq. Вот почему сравнение Foo::Bar == a терпит неудачу.

enum Foo {Bar}

fn main() {

let a = Foo::Bar;

// Переменная соответствует Foo::Bar

if Foo::Bar == a {

// ^-- это вызовет ошибку компиляции. Используйте `if let` вместо этого.

println!("a is foobar");

}

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Смотрите также:

enum, Option, и RFC

Загрузка...