F#新关键字.它是为了什么?

And*_*dry 17 f# constructor class

在F#类和记录的所有示例中,我看到记录通过new关键字或仅通过类型名称实例化/创建类.

例如,如果我有这个记录:

type MyRecord = {field1: int; field2:int}
let myvar = {new MyRecord with field1 = 3 and field2 = 3}
let myvar2 = {MyRecord with field1 = 1 and field2 = 2}
let myvar3 = {field1 = 34; field2 = 23}
Run Code Online (Sandbox Code Playgroud)

他们似乎都是一样的.这个例子也是一样的:

type MyClass(x: int) =
   let mutable xx = x
let myvar = MyClass(12)
let myvar2 = new MyClassw(234)
Run Code Online (Sandbox Code Playgroud)

那么新的东西是什么?谢谢

啊......我知道关于课程的新问题有答案,但没有提及记录.此外,我不明白为什么在构建课程时新的应该是一个可选的和无关紧要的关键工作?是否有可能在课程中使用new或不使用它确实没有变化?

Tim*_*son 23

new关键字通常不用于实例化F#记录.第一个例子是记录声明的OCaml-ish语法:

let myvar = {new MyRecord with field1 = 3 and field2 = 3}
// Normal F#: let myvar = { MyRecord.field1 = 3; field2 = 3}
Run Code Online (Sandbox Code Playgroud)

第二个例子不再编译:

// Not F#: let myvar2 = {MyRecord with field1 = 1 and field2 = 2}
Run Code Online (Sandbox Code Playgroud)

对于课程,您可以随时省略new.但是,如果在IDisposable不使用new关键字的情况下实例化类,则会收到编译器警告.

// These two are the same
let myvar = MyClass(12)
let myvar2 = new MyClass(234)

// Compiler warning
let f = FileStream("hello.txt", FileMode.Open)

// No warning
use f = new FileStream("hello.txt", FileMode.Open)
Run Code Online (Sandbox Code Playgroud)

编辑:回应您的评论 -

是不是有规则或理由为什么新的如此"灵活"?为什么使用或不使用new用于类

new是可选的 - 我不知道使其灵活的理由; 如果有某种方式的指导,那就太好了.(我的首选是永远不要使用new,除非响应编译器警告.)

为什么在实现IDisposable时会收到编译器警告

因为我从来没有new正常使用过,所以我认为这是编译器提醒我写use或者using分配时的方法IDisposable.

为什么记录不使用我之前写的第二种语法?

{ new MyRecord with ... }是Haskell语法.它可能在其中一个F#编译器测试版中有效,但它不解析F#2.0.(为什么你认为这应该有效?)

我正试图找到一个通用的逻辑规则/指南,而不是通过一堆或分散的语法规则来学习...

我知道你的感受 - F#有点像这样,特别是当你来自像C#这样的语言时,那里有正确的方法和错误的做法.我的建议是选择其中一种替代方案并坚持下去.

这可能会有所帮助:来自Microsoft 的F#组件设计指南 [PDF].这是你的F#代码的一套建议 - 注意事项.

  • 这是猜测.我认为F#试图尽可能简洁.如果你看一下类型系统; 除非存在歧义,否则您不必编写任何类型.如果将其传递给`new`关键字,如果可以从上下文中推断出它,则可以省略它.`IDisposable`可以与`new`和`use`一起使用,因此警告. (2认同)