F# new keyword. What is it for?

2020-05-25 07:50发布

问题:

In all examples of F# classes and records I see that records an classes are instantiated/created via new keyword or simply by the type name.

So for example if I have this record:

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}

They seem to be all the same. It is the same for this example too:

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

Well what is new for?? Thnkyou

Ah... I know that there are answers for the question of new regarding classes, but there is no mention for records. Furthermore, I do not understand why new should be an optional and abosultely indifferent keywork when constructing classes? Is it possible that using new or not using it for classes does change nothing?

回答1:

The new keyword is typically not used to instantiate F# records. The first example is the OCaml-ish syntax for record declarations:

let myvar = {new MyRecord with field1 = 3 and field2 = 3}
// Normal F#: let myvar = { MyRecord.field1 = 3; field2 = 3}

The second example doesn't compile any more:

// Not F#: let myvar2 = {MyRecord with field1 = 1 and field2 = 2}

For classes, you can always omit new. However, you get a compiler warning if you instantiate an IDisposable class without using the new keyword.

// 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)

Edit: In response to your comment -

isn't there a rule or s rationale why new is so "flexible"? Why is it the same using or not using new for classes

new is optional - I'm not aware of a rationale for making it flexible; it would be nice if there was some guidance one way or the other. (My preference is to never use new, except in response to the compiler warning.)

why do I get a compiler warning when implementing IDisposable

Since I never use new normally, I take this to be the compiler's way of reminding me to write use or using when I allocate an IDisposable.

and why records do not use the second syntax I wrote before?

{ new MyRecord with ... } is the Haskell syntax. It may have been valid in one of the F# compiler betas, but it doesn't parse on F# 2.0. (Why do you think this ought to be valid?)

I'm trying to find a general logic rule/guideline rather than learning byheart a bunch or scattered syntax rules...

I know how you feel -- F# is a little like this, particularly when you come from a language like C#, where there's a right way and a wrong way to do something. My advice is to pick one of the alternatives and stick to it.

This may help: the F# Component Design guidelines [PDF] from Microsoft. It's a set of advice -- dos and don'ts -- for your F# code.