我经常使用详细语法来创建通常为几行的单行表达式。通常我这样做,所以我可以使用Alt+'
将整个表达式发送到F#interactive。例如,我可能会这样做:
let longLength list = let rec helper result = function [] -> result | _ :: t -> helper (result + 1L) t in helper 0L list
对于示例代码,假设已打开这些名称空间:
open System
open System.Collections
open System.Collections.Generic
我想将此对象表达式转换为单行:
let emptyEnumerator = {
new IEnumerator<int> with member t.Current = raise(InvalidOperationException())
interface IEnumerator with
member t.MoveNext() = false
member t.Reset() = ()
member t.Current = raise(InvalidOperationException())
interface IDisposable with member t.Dispose() = ()
}
我发现我只能使用详细语法来完成它。通常,详细语法代码也会在轻量级语法下编译,但在这里,它不会。我也尝试使用相同的实现创建一个命名类,并且几乎相同的代码在轻量级和详细语法下编译:
open System
open System.Collections
open System.Collections.Generic
#light "off"
type A() = class interface IEnumerator<int> with member t.Current = raise(InvalidOperationException()) end interface IEnumerator with member t.MoveNext() = false member t.Reset() = () member t.Current = raise(InvalidOperationException()) end interface IDisposable with member t.Dispose() = () end end
let b = { new IEnumerator<int> with member t.Current = raise(InvalidOperationException()) end interface IEnumerator with member t.MoveNext() = false member t.Reset() = () member t.Current = raise(InvalidOperationException()) end interface IDisposable with member t.Dispose() = () end end }
#light "on"
type C() = class interface IEnumerator<int> with member t.Current = raise(InvalidOperationException()) end interface IEnumerator with member t.MoveNext() = false member t.Reset() = () member t.Current = raise(InvalidOperationException()) end interface IDisposable with member t.Dispose() = () end end
let d = { new IEnumerator<int> with member t.Current = raise(InvalidOperationException()) end interface IEnumerator with member t.MoveNext() = false member t.Reset() = () member t.Current = raise(InvalidOperationException()) end interface IDisposable with member t.Dispose() = () end end }
两个类定义都成功,但最后一行失败,带有“~vsB756.fsx(29,150):错误FS0010:表达式中的意外关键字'member'。在此点或其他标记之前或之前的预期不完整结构化构造。”
问题似乎出现在一系列成员定义中。 Visual Studio突出显示定义member
部分中的第二个和第三个IEnumerator
关键字,作为FS0010错误的原因。 (换句话说,突出显示的member
关键字是引入IEnumerator.Reset()
和IEnumerator.Current
定义的关键字。)
Visual Studio还会在end
实现之前的开放式大括号(不匹配的“{”)和IDisposable
关键字上报告“let”(不完整的值或函数定义)上的错误,但是我怀疑这是因为它未能识别IEnumerator
实现中的三个成员,这导致它尝试解析其他成员作为第一个成员定义的一部分。
我是否忽略了语法中的某些内容?这是编译器中的错误吗?