F#中的类型推断和new关键字

7

使用F# 2.0和FSI,我有以下代码:

let foo = List(xs)//works
let bar = new List(xs) //need type parameter 'The type System.Collectsion.Generic<_> expects 1 type argument 0 was given

现在,我当然可以这样做:

let baz = new List<TypeOItemsInXs>(xs)//why?

现在我是否有合理的解决方法?为什么我必须在工作类型推断或无警告代码之间进行选择(如果“List”是可处理的,则会得到一个警告,建议您使用“new”来明确表示)。

有什么解决办法吗?这是一个错误还是其他原因引起的?

2个回答

13

你仍然可以在通配符_中使用类型推断:

open System.Collections.Generic
let xs = [1;2;3]

let bar = new List<_>(xs)

顺便提一下,为了区分 F# 的列表和 .NET 的 List<T> 容器,F# 将 .NET 的 List<T> 重命名为 ResizeArray<T>,它位于 Microsoft.FSharp.Collections 中,并且该命名空间默认已打开:

let bar2 = new ResizeArray<_>(xs)

8
Yin Zhu的回答是正确的,我想补充一点细节。在F#中,您可以使用或不使用new关键字调用.NET构造函数。如果省略new,则无需添加通用参数,但如果使用new,则必须添加通用参数,即使您使用通配符_让类型推断完成工作。

因此,您可以这样说:

> ResizeArray([1; 2; 3;]);;
val it : System.Collections.Generic.List<int> = seq [1; 2; 3]

或者

> new ResizeArray<_>([1; 2; 3;]);;
val it : ResizeArray<int> = seq [1; 2; 3]

但不包括:

> new ResizeArray([1; 2; 3;]);;

  new ResizeArray([1; 2; 3;]);;
  ----^^^^^^^^^^^

C:\Temp\stdin(5,5): error FS0033: The type 'Microsoft.FSharp.Collections.ResizeArray<_>' expects 1 type argument(s) but is given 0

在我看来这样甚至更好,new是多余的。 - Daniel
此外,我认为在创建 IDisposable 时应该使用 "use" 关键字与 "new" 一起使用,否则应省略。 - Alex
1
是的,我的问题是我有一个可丢弃类型,并且省略 new 会出现警告。如果我添加 new,那么正如 Yin Zhu 指出的那样,我可以使用通配符。只是感觉语言这样不对称有点奇怪 :S - Torbjörn Gyllebring

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