如何在F#中编写无操作语句?
具体来说,如何改进以下匹配语句的第二个子句:
match list with
| [] -> printfn "Empty!"
| _ -> ignore 0
Run Code Online (Sandbox Code Playgroud)
Str*_*ger 30
使用单位为空副作用:
match list with
| [] -> printfn "Empty!"
| _ -> ()
Run Code Online (Sandbox Code Playgroud)
Tom*_*cek 16
斯金格的答案当然是正确的.我认为澄清它是如何工作的可能是有用的,因为"()"实际上并不是一个空的陈述或空的副作用......
在F#中,每个有效的代码片段都是一个表达式.构造像let和match由一些关键字,模式和几个子表达式.F#语法为let和match看起来像这样:
<expr> ::= let <pattern> = <expr>
<expr>
::= match <expr> with
| <pat> -> <expr>
Run Code Online (Sandbox Code Playgroud)
这意味着let条款的主体或主体match必须是某种表达方式.它可以是一些函数调用,ignore 0或者它可以是一些值 - 在你的情况下它必须是一些类型的表达式unit,因为printfn ".."它也是类型unit.
该unit类型是具有只有一个值,其被写为一个类型()(它也意味着没有元素空的元组).这确实有点类似于voidC#,void但没有任何值.
BTW:以下代码可能看起来像一系列语句,但它也是一个表达式:
printf "Hello "
printf "world"
Run Code Online (Sandbox Code Playgroud)
F#编译器隐式地;在两行之间添加,并且;是一个排序运算符,它具有以下结构:<expr>; <expr>.它要求第一个表达式返回unit并返回第二个表达式的结果.
当你来自C#背景时,这有点令人惊讶,但它使得语言非常优雅和简洁.它不会以任何方式限制你 - 例如你可以写:
if (a < 10 && (printfn "demo"; true)) then // ...
Run Code Online (Sandbox Code Playgroud)
(这个例子并不真正有用 - 只是演示了灵活性)