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可以看到它。非常感谢!对我来说很有魅力,谢谢。无法想象解决方案会如此简单: