为什么下面的代码没有编译?这是编译器错误还是语言功能?什么是最好的解决方法?
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&LT;'T&GT;仅用于示例,可以使用任何函数或构造函数调用。
编译器说代码在(a)行变得不那么通用,并且拒绝编译行(b)。 我无法提供确切的编译器消息,因为我用俄语提供它们:)。
将方法GetTypedObject()转换为let绑定并删除&lt;'T&gt;最终得到另一个我不喜欢的编译器警告。我发现的唯一的问题是将GetTypedObject&lt;'T&gt;()移动到基类中并使其公开。提前谢谢......
答案 0 :(得分:4)
请注意,您只需添加类型注释即可解决此问题:
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和成员主体。通过将返回类型放在声明签名中,它将变为可见。
答案 1 :(得分:3)
由于类型推断从上到下工作,在遇到方法定义之前遇到。 (正如Brian指出的那样,成员在GetTypedObject
返回int
并发现它应该是通用的let
绑定之前被读取......并且有一个更简单的解决方法。)我得到以下令人讨厌的错误:
“GetTypedObject”函数的使用与其他地方推断的类型不匹配。推断的函数类型是Test.A - &gt; Microsoft.FSharp.Core.unit - &gt; '一个。在这个使用点所需的功能类型是Test.A - &gt; Microsoft.FSharp.Core.unit - &gt; '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()