Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Generics 泛型的麻烦_Generics_F# - Fatal编程技术网

Generics 泛型的麻烦

Generics 泛型的麻烦,generics,f#,Generics,F#,为什么下面的代码不编译?这是编译器错误还是语言特性?最好的解决办法是什么 type A() as this = let a = this.GetTypedObject<int>() // a let b = this.GetTypedObject<string>() // b member this.GetTypedObject<'T>() = Unchecked.defaultof<'T> Unc

为什么下面的代码不编译?这是编译器错误还是语言特性?最好的解决办法是什么

type A() as this =
    let a = this.GetTypedObject<int>()    // a
    let b = this.GetTypedObject<string>() // b

    member this.GetTypedObject<'T>() =
        Unchecked.defaultof<'T>

Unchecked.defaultof最后会出现另一个我也不喜欢的编译器警告。我发现的唯一一个wokaround是移动GetTypedObject,因为类型推断是自上而下工作的,它遇到GetTypedObject返回int,甚至在它到达方法定义之前,就发现它应该是泛型的。正如Brian所指出的,在让绑定之前先阅读成员…有一个更简单的修复方法。我犯了以下严重错误:

函数“GetTypedObject”的使用与在别处推断的类型不匹配。推断出的函数类型是Test.A->Microsoft.FSharp.Core.unit->'A。此使用点所需的函数类型为Test.A->Microsoft.FSharp.Core.unit->“A此错误可能是由于与“let rec”集合或一组类中的泛型递归相关的限制造成的。考虑为递归调用的目标提供完整的类型签名,包括参数和返回类型的类型注释。

如果用法出现在方法定义之后,则该用法有效

type A() =
    member this.GetTypedObject<'T>() =
        Unchecked.defaultof<'T>

    member this.Test() =
      let a = this.GetTypedObject<int>()    // a
      let b = this.GetTypedObject<string>() // b
      ()
这里有一个解决方法:

type A() =
  let getTypedObject() = Unchecked.defaultof<_>
  let a : int = getTypedObject()    // a
  let b : string = getTypedObject() // b

  member this.GetTypedObject<'T>() : 'T = getTypedObject()

请注意,您只需添加类型注释即可解决此问题:

type A() as this = 
    let a = this.GetTypedObject<int>()    // a 
    let b = this.GetTypedObject<string>() // b 

    member this.GetTypedObject<'T>() : 'T = 
                                   //^^^^
        Unchecked.defaultof<'T> 

当涉及到类型推断的顺序时,首先读取成员签名,然后读取所有let和成员体。通过将返回类型放在声明签名中,let可以看到它。

非常感谢!对我来说很有魅力,谢谢。无法想象解决方案会如此简单: