Ответ от Stringer , конечно, правильный. Я подумал, что было бы полезно уточнить, как это работает, потому что "()" на самом деле не пустой оператор или пустой побочный эффект ...
В F #, каждый допустимый фрагмент кода является выражением . Конструкции типа let
и match
состоят из нескольких ключевых слов, шаблонов и нескольких подвыражений. Грамматика F # для let
и match
выглядит следующим образом:
<expr> ::= let <pattern> = <expr>
<expr>
::= match <expr> with
| <pat> -> <expr>
Это означает, что тело let
или тело предложения match
должно быть некоторым выражением. Это может быть вызов некоторой функции, такой как ignore 0
, или это может быть какое-то значение - в вашем случае это должно быть выражение типа unit
, поскольку printfn ".."
также имеет тип unit
.
Тип unit
- это тип, который имеет только одно значение, которое записывается как ()
(и это также означает пустой кортеж без элементов). Это действительно немного похоже на void
в C # за исключением того, что void
не имеет каких-либо значений.
Кстати: следующий код может выглядеть как последовательность операторов, но также является выражением:
printf "Hello "
printf "world"
Компилятор F # неявно добавляет ;
между двумя строками, а ;
является оператором последовательности, который имеет следующую структуру: <expr>; <expr>
. Требуется, чтобы первое выражение возвращало unit
и возвращало результат второго выражения.
Это немного удивительно, когда вы начинаете с C #, но это делает язык на удивление элегантным и лаконичным. Это никак не ограничивает вас, например, вы можете написать:
if (a < 10 && (printfn "demo"; true)) then // ...
(Этот пример не очень полезен - просто демонстрация гибкости)