有没有办法将一个带有参数的函数赋值给一个函数变量的子类,参数是它的超类?这是我的意思的一个例子:
class ClassA {}
class subclassOfA:ClassA {}
func subclassToNil(argument:subclassOfA) -> (){}
var functionVariable:(ClassA->())
funcVar = subclassToNil
这会引发类型不兼容的异常。
答案 0 :(得分:2)
我不敢 - 你已经发现了"协方差"和"逆转"。函数类型与其参数(参数)是逆变的,这意味着如果需要,您可以提供超类,但不能提供子类。另一方面,使用返回值,函数类型是协变的,如果您愿意,可以返回子类。
经过一番思考,这些规则是有道理的:
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.
因此,使用 less 特定的参数是安全的。返回值的推理非常相似,您可以在逻辑上看到,更多特定的那些。