F# 未知是否需要类型批注或强制转换
我知道我一定错过了一些很明显的东西F# 未知是否需要类型批注或强制转换,f#,type-inference,F#,Type Inference,我知道我一定错过了一些很明显的东西B.GetInstance().Call()生成错误:基于此程序点之前的信息查找不确定类型的对象。在此程序点之前可能需要类型注释来约束对象的类型。这样可以解决查找问题 我使用的是v1.9.9.9 type A() = member x.Call() = B.GetInstance().Call() and B() = static member GetInstance() = new B() member x.Call() = ()
B.GetInstance().Call()
生成错误:基于此程序点之前的信息查找不确定类型的对象。在此程序点之前可能需要类型注释来约束对象的类型。这样可以解决查找问题
我使用的是v1.9.9.9
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() = new B()
member x.Call() = ()
我刚刚发现这是可行的:(B.GetInstance():>B.Call()
知道为什么强制转换是必要的吗?当你有一组递归的方法要推断其类型时,F#需要帮助。一个更令人愉快的选择是注释
B.GetInstance
的定义:
type A() =
member x.Call() = B.GetInstance().Call()
and B() =
static member GetInstance() : B = new B()
member x.Call() = ()
我相信你遇到这个问题的原因是F#试图同时解决A和B中所有方法上的所有推断类型(因为它们被定义为相互递归的类型),这会导致问题,但也许F#团队的某个人会参与进来。快速总结是递归组中的类型(例如,一种类型中的成员,或者像我们这里这样的递归类型的成员)F#按照从左到右的从上到下的顺序读取声明,然后按照从左到右的从上到下的顺序读取定义。因此,在本例中,当它到达
A.Call
的定义时,它尚未读取B.GetInstance
的定义,因此不会(现在!)知道GetInstance
的返回类型将是B
Keith的回答明确了这种情况,您可以提供一个类型注释,在其声明中指定GetInstance
的返回类型
看
对这里发生的事情进行深入的讨论
还要注意的是,在最初的尝试中,您不需要“强制转换”(潜在的动态操作,使用
:>
),而是可以“注释”(静态声明一个类型,使用:
)来编译它。但是将类型注释放在GetInstance
的方法声明中更有意义(一般来说,与方法签名相比,更喜欢添加注释,而不是正文中的任意位置)。这不是直观的理解方法。节省了我的时间,谢谢!