我有通用课程 - Class1
。
class Class1<T> {
}
我的Class2
变量object1
类型为Class1
,泛型类型UIView
class Class2 {
var object1: Class1<UIView>?
}
当我创建Class2
的实例并尝试分配object1
类型为Class1
的实例和泛型类型UITableView
时,我收到错误:“无法分配类型的值Class1<UITableView>
要输入Class1<UIView>
“
var c = Class2()
c.object1 = Class1<UITableView>()
然而,相同的逻辑适用于Array。为什么呢?
答案 0 :(得分:1)
让我详细说明安东的评论。问题是当你可以将B用作A时。通常,当B是A的子类型时,你可以这样做。例如,你可以将UITableView
分配给UIView
类型的变量。 / p>
那么什么时候是其他东西的子类型呢?
对于类,这很简单:如果您从B
继承A
,B
是A
的子类型。
对于函数类型,您需要考虑参数类型和返回类型。函数类型F2
是函数类型F1
的子类型,如果F2
的参数类型是F1
的参数和F2
的返回类型的超类型是F1
的返回类型的子类型。你可以说一个函数不能要求更多(即它不能要求子类型作为参数但可以要求超类型)并且不能提供更少(即它必须不返回超类型但可以返回子类型),因为它的类型是子类型。术语是参数类型必须是逆变,返回类型必须是协变。
示例:
var f1: UIControl -> UIControl = ...
let f2: UIView -> UIControl = ...
let f3: UIControl -> UIButton = ...
let f4: UIView -> UIButton = ...
f1 = f2 // Fine, f2 takes UIView so it also takes UIControl
f1 = f3 // Fine, f3 returns UIButton which is a UIControl
f1 = f4 // Fine, both of the above
let f5: UIButton -> UIControl
let f6: UIControl -> UIView
let f7: UIButton -> UIView
f1 = f5 // Error, couldn’t call with a UIControl because f5 demands at least a UIButton
f1 = f6 // Error, call would return only a UIView
f1 = f7 // Error, both of the above
因此f2
,f3
和f4
的类型是f1
类型的子类型和f5
的类型,{{1} },f6
不是。
现在通用类型怎么样?在Swift中,具有类型参数的自定义类型都是不变的。也就是说,在您的示例中,无论f7
和Class1<T2>
之间的关系如何,Class1<T1>
对象都可以用作T1
对象(T2
除外) T1
属于同一类型。)
但是,Swift确实有一些内置的方差规则,这些规则可以使您的数组示例有效:T2
([UITableView]
)是Array<UITableView>
的子类型([UIView]
) 。请注意,选项也是如此,即Array<UIView>
(UITableView?
)是Optional<UITableView>
(UIView?
)的子类型。因此,数组和选项都与它们的类型参数协变。
进一步阅读: