F#显式构造函数参数括号问题:VS2013为何对第四类报错?
解析F#中ClassFour构造函数的编译歧义
首先把你的代码贴出来方便分析:
type ClassOne = val mutable myint: int new (j) = { myint= j } new () = ClassOne 1 type ClassTwo = val mutable myint: int new j = { myint= j } new () = ClassTwo 2 type ClassThree = val mutable myint: int new j = { myint= j } new () = ClassThree 3 type ClassFour = val mutable myint: int new j = { myint= j } new () = ClassFour 4 // confusion here
咱们来拆解编译器的理解逻辑:
F#是对缩进敏感的语言,类的所有成员(包括多个构造函数)都需要通过缩进或者大括号包裹来明确归属到当前类。前三个类能正常工作,大概率是编辑器帮你隐式处理了缩进,或者你实际编写时的格式符合要求,但ClassFour的写法在既无括号又无错位缩进的情况下,编译器会做出完全错误的解析:
- 首先,
new j = { myint= j }这部分会被正确识别为ClassFour的一个构造函数(接受参数j并初始化myint)。 - 但后面的
new () = ClassFour 4因为没有缩进,编译器会直接认为你已经写完了ClassFour的定义,接下来是要在类定义的外部,创建一个名为new的顶级函数——这个函数接受空参数列表,函数体是调用ClassFour 4并返回结果。
这显然会触发两个致命错误:
new是F#的保留关键字,根本不能用来命名普通函数;- 此时ClassFour的定义还没完成(编译器认为类在第一个构造函数后就结束了),
ClassFour这个类型还不存在,自然无法调用它。
简单来说,编译器完全没把后面的new () = ...当成ClassFour的一部分,而是把它当成了一个独立的、语法错误的函数定义。
内容的提问来源于stack exchange,提问作者Robert Nielsen
相关产品推荐
相关产品推荐

