Есть ли точки с запятой в Rust?

Так как точки с запятой, по-видимому, необязательны в Rust, почему, если я это сделаю:

fn fn1() -> i32 {    
    let a = 1
    let b = 2
    3
}

Я получаю сообщение об ошибке:

error: expected one of `.`, `;`, `?`, or an operator, found `let`
 --> src/main.rs:3:9
  |
2 |         let a = 1
  |                  - expected one of `.`, `;`, `?`, or an operator here
3 |         let b = 2
  |         ^^^ unexpected token

?

Ответ 1

Они не являются необязательными. Точки с запятой изменяют поведение оператора выражения, поэтому оно должно быть сознательным решением, используете ли вы их или нет для строки кода.

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

С другой стороны, это означает, что если вы закончите свою функцию выражением без точки с запятой, результат этого последнего выражения будет возвращен. То же самое можно применить к блоку в инструкции match.

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

Например:

let a = {
    let inner = 2;
    inner * inner
};

Здесь выражение inner * inner не заканчивается точкой с запятой, поэтому его значение не подавляется. Поскольку это последнее выражение в блоке, его значение будет возвращено и назначено на a. Если вы положите точку с запятой в эту же строку, значение inner * inner не будет возвращено.

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