我试图创建一个类结构,该类结构有一个具有泛型类型(带有类型约束)的类,它被用作另一个泛型类的泛型类型约束。一旦我尝试子类化第一个类型约束类,该子类就不再可用于初始化第二个泛型类(但对第一个类工作正常)。这是一个简化的代码示例:
class DataClass {
var value: Int
required init(value: Int) {
self.value = value
}
}
class Thing: DataClass {
required init(value: Int) {
super.init(value: value)
}
}
class ThingWrapper<ThingDataType: Thing>: DataClass {
var thing: ThingDataType
required init(value: Int) {
thing = ThingDataType(value: value)
super.init(value: value)
}
}
class ThingWrapperList<ThingWrapperType: ThingWrapper<Thing>>: DataClass {
var things: [ThingWrapperType]
required init(value: Int) {
things = [ThingWrapperType]()
super.init(value: value)
}
}
这些工作正常:
var thingWrapper = ThingWrapper<Thing>(value: 42)
var thingWrapperList = ThingWrapperList<ThingWrapper<Thing>>(value: 42)
就像这样:
class NewThing: Thing {
required init(value: Int) {
super.init(value: value)
}
}
var newThingWrapper = ThingWrapper<NewThing>(value: 42)
但这会产生错误:
var newThingWrapperList = ThingWrapperList<ThingWrapper<NewThing>>(value: 42)
Error: 'ThingWrapperList' requires that 'ThingWrapper<NewThing>' inherit from 'ThingWrapper<Thing>'
那么我可以不使用内部类型泛型约束的子类吗?我可以通过摆脱&#34; ThingWrapper&#34;来解决这个问题。上课,但我试图模仿我的JSON格式,现在我很好奇我做错了什么。
答案 0 :(得分:1)
当前Swift的实现并不支持这一点,因为它不支持(但)支持泛型中的协方差或逆变,这意味着您需要在专门化类型中完全匹配。
我们可以尝试用更小的例子来简化这个。我们假设我们有以下类层次结构:
class A1 {}
class A2: A1 {}
class B1<T: A1> {}
class B2<T: A1>: B1<T> {}
我们可以检查Swift强制执行的规则:
// These first 3 assignments compile correctly:
let a: A1 = A2() // because A2 inherits from A1
let b: B1<A1> = B2<A1>() // because B2 inherits from B1 and A1 == A1
let b2: B1<A2> = B2<A2>() // because B2 inherits from B1 and A2 == A2
// The next 2 assignments do not compile in current Swift
// due to the lack of covariant generics
let b3: B1<A1> = B1<A2>() // cannot convert value of type 'B1<A2>' to specified type 'B1<A1>'
let b4: B1<A1> = B2<A2>() // cannot convert value of type 'B2<A2>' to specified type 'B1<A1>'
要复制您的问题,我们需要添加另一个图层,所以让我们创建一个函数:
func C<T: A1>(_ arg: B1<T>) {}
C(B1<A1>())
C(B1<A2>())
C(B2<A1>())
C(B2<A2>())
这一切都成功编译,因为我们添加了另一个通用参数来处理所需的特化,而不是试图依赖协方差。
总之,要在Swift中表达您的类heirarchy,您需要向ThingWrapperList
添加另一个通用参数:
class ThingWrapperList<ThingDataType, ThingWrapperType: ThingWrapper<ThingDataType>>: DataClass
在此声明中,ThingWrapperList
在ThingWrapperType
和 ThingDataType
上是通用的,因此您可以使用Thing
或{{1 }}