Почему выражение соответствия не сообщает об ошибке для универсальной руки (_) до других рук? - PullRequest
0 голосов
/ 31 мая 2018

Rust имеет конструкцию под названием match, которая очень похожа на switch в других языках.Однако я наблюдал очень своеобразное поведение match.

let some_u32_value = 3;
match some_u32_value {
    _ => (),
    3 => println!("three"),
}

match в соответствии с порядком, в котором упоминаются случаи / паттерны.Почему он не сообщает об ошибке, если регистр по умолчанию (_) находится сверху?Однако он выдает предупреждение:

warning: unreachable pattern
 --> src/main.rs:5:9
  |
5 |         3 => println!("three"),
  |         ^
  |
  = note: #[warn(unreachable_patterns)] on by default

Аналогичная конструкция в Java, коммутатор, не сохраняет ни одного порядка, поэтому наличие default перед другими случаями не является ошибкой (игнорирование провалаповедение).

int x = 0;

switch (x) {
  default:
    System.out.println("default");
    break;
  case 0:
      System.out.println("Zero");
} 

Есть ли какая-то цель сделать это явно?

Ответы [ 2 ]

0 голосов
/ 31 мая 2018

Выражения Rust match намного мощнее, чем операторы Java switch, и вы можете сделать намного больше, чем просто сопоставление чисел.

В частности, оно поддерживает сопоставление с шаблоном который позволяет вам сопоставлять фрагменты ваших данных, исходя из их структуры или значений, которые он содержит.Когда у вас есть более сложные шаблоны для сопоставления, важно иметь возможность указать порядок, потому что шаблоны могут перекрываться.Например:

let value = Some((Some(3), "hello"));

let s = match value {
    None => "Nothing there!".to_owned(),
    Some((Some(3), _)) => "The number is exactly 3!".to_owned(),
    Some((Some(n), _)) if n > 3 => format!("Got a number bigger than 3: {}", n),
    Some((None, msg)) => format!("Message with no number: {}", msg),
    Some((_, msg)) => format!("Got the message, ignore the rest: {}", msg),
    _ => "Anything else?".to_owned()
};

println!("result = {}", s);

Последний случай здесь фактически невозможен, потому что все остальные ветви охватывают все.Компилятор выдаст предупреждение, если это не то, что вы хотели.

0 голосов
/ 31 мая 2018

Недоступный шаблон не является строго ошибкой, я имею в виду: он не мешает компилятору «понимать» код и не делает его небезопасным.

Аналогично, например, в CВы можете вернуть ссылку на локальную переменную, не вызывая ошибки (по крайней мере, с gcc):

#include <stdio.h>

int* foo() {
    int x = 0;

    return &x;
}

int main() {
    printf("%d", *foo());

    return 0;
}

Как правило, вы не должны рассматривать предупреждение как "о, это только предупреждение, мне все равно ".Предупреждение - это полезный совет / информация, предоставленная компилятором.

Мне нравится определение, данное в :

Предупреждение часто выдается при распознаваниипотенциальная ситуация высокого риска, возможное недоразумение, ухудшение обслуживания или неизбежный сбой.

, поскольку это помогает понять разницу между ошибкой и предупреждением:

  • Anошибка - это ошибка,
  • Предупреждение - это потенциальная / вероятная ошибка или проблемная вещь.

В этой ситуации последний рычаг match это некоторый мертвый код, поэтому компилятор сообщает об этом соответственно.

...