无法分配泛型类型的值

时间:2016-12-26 08:04:00

标签: ios swift generics

我有通用课程 - 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。为什么呢?

enter image description here

1 个答案:

答案 0 :(得分:1)

让我详细说明安东的评论。问题是当你可以将B用作A时。通常,当B是A的子类型时,你可以这样做。例如,你可以将UITableView分配给UIView类型的变量。 / p>

那么什么时候是其他东西的子类型呢?

对于类,这很简单:如果您从B继承ABA的子类型。

对于函数类型,您需要考虑参数类型和返回类型。函数类型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

因此f2f3f4的类型是f1类型的子类型和f5的类型,{{1} },f6不是。

现在通用类型怎么样?在Swift中,具有类型参数的自定义类型都是不变的。也就是说,在您的示例中,无论f7Class1<T2>之间的关系如何,Class1<T1>对象都可以用作T1对象(T2除外) T1属于同一类型。)

但是,Swift确实有一些内置的方差规则,这些规则可以使您的数组示例有效:T2[UITableView])是Array<UITableView>的子类型([UIView]) 。请注意,选项也是如此,即Array<UIView>UITableView?)是Optional<UITableView>UIView?)的子类型。因此,数组和选项都与它们的类型参数协变。

进一步阅读: