F#:为什么可以';当B是a的子类型时,将B类型的对象约束为a类型的列表?
根据本网站的第三个示例,F#列表可以包含不同类型的对象,只要这两种类型都来自同一个超级类型。但是,我无法让cons(::)操作符将子类型添加到超类型列表中F#:为什么可以';当B是a的子类型时,将B类型的对象约束为a类型的列表?,f#,F#,根据本网站的第三个示例,F#列表可以包含不同类型的对象,只要这两种类型都来自同一个超级类型。但是,我无法让cons(::)操作符将子类型添加到超类型列表中 module test type A() = member this.x = 2 type B() = inherit A() member this.y = 4 let mutable myList : A list = [] myList <- [B()] // Valid myList <- B
module test
type A() =
member this.x = 2
type B() =
inherit A()
member this.y = 4
let mutable myList : A list = []
myList <- [B()] // Valid
myList <- B()::myList // Invalid: This expression was expected to have type A but here has type B
模块测试
A型()=
成员:x=2
B类()=
继承
成员:y=4
让可变myList:A list=[]
myListF#并不总是自动插入向上转换(转换为基本类型),因此您必须插入一个显式转换,将B
值转换为a
类型的值
请注意,F#区分了向基类的向上转换(总是正确的)和向派生类的向下转换(可能失败的)
您可以使用upcast
关键字,也可以使用expr:>类型
符号。在这两种情况下,编译器都可以填写所需的目标类型,因此您只需编写:
myList <- (upcast B())::myList
myList <- (B() :> _)::myList
myList Trylet mutable myList:#列表=[]
或myList@ildjarn您的第一个建议会导致一个警告:此构造导致代码没有其类型注释所指示的那么通用。在或附近使用“#”、“"”或其他类型批注所隐含的类型变量已被约束为类型“B”。你的第二个建议似乎有效。