我正在看下面的F#系列
for i = 0 to i=10 do
Console.WriteLine("Hello")
Run Code Online (Sandbox Code Playgroud)
我想知道上述行不是一个声明而不是表达式吗?
难道一切都不应该成为F#的表达吗?
如前所述,F#中的每个语法结构都是一个表达式.F#不语句和表达式( - F#不和,所以我会说,维基百科引用作者:罗伯特是有点误导区分有语句).
实际上,上述情况并不完全正确,因为F#计算表达式中的某些结构let!
不是表达式,但我们可以忽略它.
那是什么意思?在C#中,语法for
和方法调用的定义如下:
statement := foreach(var v in <expression>) <statement>
| { <statement> ... <statement> }
| <expression>;
| (...)
expression := <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
Run Code Online (Sandbox Code Playgroud)
这是非常简化的,但它应该给你一个想法 - 一个语句不会评估为一个值.它可以是foreach
循环(其他循环),语句块(具有多个语句)或带分号的表达式(其中表达式的结果void
被忽略).表达式例如是方法调用,原始文字(字符串,整数)或二元运算符.
这意味着您无法在C#中编写某些内容 - 例如,方法调用的参数不能是一个语句(因为语句不会计算为值!)
另一方面,在F#中,一切都是表达式.这意味着只有一个句法类别:
expression := for v in <expression> do <expression>
| <expression>; <expression>
| <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
Run Code Online (Sandbox Code Playgroud)
这意味着在F#中,所有语法结构都是表达式,包括for
其他循环.主体for
也是一个表达式,但是如果表达式被评估为某个值(即42
),那么这些类型要求主体的结果是unit
(它不携带任何信息)是没有意义的.同样,sequencing(<expr>; <expr>
)中的第一个表达式应该返回unit
- 排序的结果是第二个表达式的结果.
这使得语言更简单,更统一,但你可以写一些奇怪的东西:
let x = (for i in 0 .. 10 do printfn "%d" i); 42
Run Code Online (Sandbox Code Playgroud)
这将打印数字0
到10
,然后定义的值x
是42
.赋值是expression(<expr>; <expr>
)的排序,其中第一个是for
循环(有一个类型unit
,因为它不计算任何东西)而第二个是42
,它的计算结果为42.