10

我注意到以下代码在 VS 2013 中编译并运行:

let f() =
    do Console.WriteLine(41)
    42

但是在查看 F# 3.0 规范时,我找不到任何提及以do这种方式使用的内容。据我所知,do可以有以下用途:

  • 作为循环的一部分(例如),这里不是这种情况。while expr do expr done
  • 内部计算表达式,例如:

    seq {
        for i in 1..2 do
        do Console.WriteLine(i)
        yield i * 2
    }
    

    这里也不是这种情况,f不包含任何计算表达式。

    虽然这里让我感到困惑的是,根据规范,do应该跟在in. in由于轻量级语法,这应该是可选的,但在此处添加它会导致编译错误(“Unexpected token 'in' or incomplete expression”)。

  • 模块或类中的语句。这里也不是这种情况,do它在函数内部,而不是在模块或类内部。

我还注意到,使用#light "off",代码无法编译(“Unexpected keyword 'do' in binding”),但我也没有在轻量级语法部分找到任何可以解释这一点的内容。

基于这一切,我假设以do这种方式在函数内部使用不应该编译,但确实如此。我错过了规范中的某些内容吗?或者这实际上是编译器或规范中的错误?

4

2 回答 2

7

From the documentation on MSDN:

A do binding is used to execute code without defining a function or value.

Even though the spec doesn't contain a comprehensive list of the places it is allowed, it is merely an expression asserted to be of type unit. Some examples:

if ((do ()); true) then ()
let x: unit = do ()

It is generally omitted. Each of the preceding examples are valid without do. Therefore, do serves only to assert that an expression is of type unit.

于 2014-07-16T14:57:28.593 回答
0

通过F# 3.0 规范表达式语法可以do expr选择class-function-or-value-defn(types) [Ch 8, A.2.5] 和module-function-or-value-defn(modules) [Ch 10, A.2.1.1]。

我实际上并没有在规范中看到function-defn可以有多个表达式,只要除最后一个之外的所有表达式都计算为unit- 或者在确定函数返回值时忽略除最后一个表达式之外的所有表达式。

因此,这似乎是文档中的疏忽。

于 2014-07-17T01:57:40.103 回答