有没有办法给函数赋一个参数,该参数是函数变量的子类,参数是它的超类?这里是我的意思的一个例子:函数类型中的swift子类
class ClassA {}
class subclassOfA:ClassA {}
func subclassToNil(argument:subclassOfA) ->(){}
var functionVariable:(ClassA->())
funcVar = subclassToNil
这引发了一个类型不兼容异常。
有没有办法给函数赋一个参数,该参数是函数变量的子类,参数是它的超类?这里是我的意思的一个例子:函数类型中的swift子类
class ClassA {}
class subclassOfA:ClassA {}
func subclassToNil(argument:subclassOfA) ->(){}
var functionVariable:(ClassA->())
funcVar = subclassToNil
这引发了一个类型不兼容异常。
恐怕不是 - 你发现了“协变”和“反转”。函数类型与它们的参数(参数)是不相容的,这意味着如果需要,您可以提供一个超类,但不是子类。与返回值另一方面,功能类型是协变,并可以返回子类如果您愿意。
随着一点点的思想,这些规则意义:
class ClassA {}
class SubclassOfA: ClassA {}
func subclassToNil(argument: SubclassOfA) ->()) {}
var functionVariable: (ClassA ->())
functionVariable = subclassToNil
functionVariable(ClassA()) //`subclassToNil` won't know what to do with this; kablooie!
但是:
class ClassParent {}
class ClassA: ClassParent {}
func subclassToNil(argument: ClassParent) ->()) {}
var functionVariable:(ClassA ->())
functionVariable = subclassToNil
functionVariable(ClassA()) //`ClassA()` is indeed a valid `ClassParent`, so we're fine.
所以它的安全使用是少具体参数。返回值的推理非常相似,从逻辑上看,您可以使用更多特定的。
这很有趣,因为我已经尝试了一个返回类型作为子类的例子,正如你所说的,编译器没有抱怨。这个例子很清楚为什么因为设置'subclassToNil'不会改变functionVariable的类型签名! – chartman
这是行不通的。 'functionVariable()'可以用'ClassA'的一个实例调用,但是该函数需要一个* subclass *的实例作为参数。 (它只会反过来工作。) –