F#新关键字。它有什么作用?

24

在所有的 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}

它们似乎都是一样的。 这个例子也是一样的:

type MyClass(x: int) =
   let mutable xx = x
let myvar = MyClass(12)
let myvar2 = new MyClassw(234)

那么 new 是用来做什么的?谢谢

啊...我知道有关于类的 new 的问题已经有答案了,但是对于记录(record)没有提到。此外,我不明白为什么在构建类时,new 应该是一个可选的并且完全无关紧要的关键字?使用 new 或者不使用它是否都不会有任何变化?


1
对于类也是一样的:参见https://dev59.com/mHI-5IYBdhLWcg3wfoW1 - elmattic
请参见 http://msdn.microsoft.com/zh-cn/library/dd233192.aspx。 - Ruben Bartelink
1个回答

29

new关键字通常不用于实例化F#记录。第一个示例是记录声明的OCaml风格语法:

let myvar = {new MyRecord with field1 = 3 and field2 = 3}
// Normal F#: let myvar = { MyRecord.field1 = 3; field2 = 3}
第二个例子不再编译:
// Not F#: let myvar2 = {MyRecord with field1 = 1 and field2 = 2}

对于类,你总是可以省略 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)

编辑:回应您的评论 -

为什么new这么“灵活”,有没有规则或基本原则?使用或者不使用对于类来说是否相同?

new是可选的 - 我不知道有没有制定其灵活性的原则;如果有指导方针倾向某一种写法那就更好了(我的偏好是除非编译器警告,否则从不使用new)。

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

由于我通常不使用new,所以我认为这是编译器提醒我在分配IDisposable时编写useusing代码的方式。

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

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

我想找到一个通用逻辑规则/指南,而不是记忆一堆分散的语法规则......

我知道您的感受 - F#有些像这样,特别是当您从C#这样的语言过来时,那里有正确和错误的做法。我的建议是选择其中一种替代方案并坚持使用。

这可能有所帮助:微软的F#组件设计指南 [PDF]。这是一组关于您的F#代码的建议 - 该做什么,不该做什么。


啊,好的,但是使用 new 关键字如此“灵活”的规则或理论不是有吗?为什么对于类来说使用或不使用 new 是一样的,而在实现 IDisposable 时却会收到编译器警告,以及为什么记录类型不使用我之前写的第二种语法?我正在尝试找到一个通用的逻辑规则/指南,而不是通过记忆一堆零散的语法规则来学习...无论如何,谢谢你的回答... - Andry
2
这只是我的猜测。我认为 F# 试图尽可能简洁。如果你看一下类型系统,除非存在歧义,否则不必编写任何类型。如果将此转移到“new”关键字,则可以在上下文中推断出它时省略它。IDisposable 可以与 newuse 一起使用,因此会出现警告。 - Markus Jarderot
+1 你确定代码中关于 IDisposableuse 缺失的警告不只是这样吗?也就是说,你没有说 use x = File.OpenRead("hello.txt") 会产生警告。 - Ruben Bartelink

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接