我正在查看以下F#行
for i = 0 to i=10 do
Console.WriteLine("Hello")
我想知道上述行不是表达式而不是表达式吗?
在F#中,一切都不应该是表达吗?
答案 0 :(得分:8)
如前所述,F#中的每个语法结构都是表达式。 F#没有区分语句和表达式(因此我会说Robert发布的WikiPedia引用有点误导 - F#没有有语句)。
实际上,上述情况并非完全正确,因为F#计算表达式中的某些结构(如let!
)不是表达式,但我们可以忽略它。
这是什么意思?在C#中,for
和方法调用的语法定义如下:
statement := foreach(var v in <expression>) <statement>
| { <statement> ... <statement> }
| <expression>;
| (...)
expression := <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
这是非常简化的,但它应该给你一个想法 - 一个语句不会评估为一个值。它可以是foreach
循环(其他循环),语句块(具有多个语句)或带分号的表达式(其中表达式的结果为void
或被忽略)。表达式例如是方法调用,原始文字(字符串,整数)或二元运算符。
这意味着您无法在C#中编写某些内容 - 例如,方法调用的参数不能是一个语句(因为语句不会计算为值!)
另一方面,在F#中,一切都是表达式。这意味着只有一个句法类别:
expression := for v in <expression> do <expression>
| <expression>; <expression>
| <expression>.<ident>(<expression>, ..., <expression>)
| <literal>
| <expression> + <expression>
| (...)
这意味着在F#中,所有语法结构都是表达式,包括for
和其他循环。 for
的主体也是一个表达式,但如果表达式求值为某个值(即42
)则没有意义,因此类型要求正文的结果为{{1} }(不带任何信息)。同样,排序中的第一个表达式(unit
)应返回<expr>; <expr>
- 排序结果是第二个表达式的结果。
这使语言更简单,更统一,但你可以写一些奇怪的东西:
unit
这会打印从let x = (for i in 0 .. 10 do printfn "%d" i); 42
到0
的数字,然后将值10
定义为x
。赋值是表达式的排序(42
),其中第一个是<expr>; <expr>
循环(类型为for
,因为它不计算任何东西),第二个是{ {1}},评估为42。
答案 1 :(得分:4)
F#中的每个语句,包括if语句和循环,都是一个 具有确定返回类型的可组合表达式。 不返回任何值的函数和表达式会返回 单位类型。
答案 2 :(得分:0)
在F#语言中,语句只是返回类型()
的值unit
的表达式。因为unit
类型只有一个值,所以它没有传递任何信息,所以返回类型单位的值是说“如果我正在做任何事情那么它是通过副作用”,比如打印到控制台或写入磁盘。
请注意,并非所有内容都是F#中的表达式。类型定义不是表达式。模式不是表达式。等等...