函数类型中的swift子类

函数类型中的swift子类,swift,function,types,Swift,Function,Types,有没有一种方法可以将具有子类参数的函数指定给具有超类参数的函数变量?以下是我的意思的一个例子: 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->())

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.

因此,使用不太具体的参数是安全的。返回值的推理非常相似,从逻辑上讲,您可以使用更具体的返回值。

这是行不通的
functionVariable()
可以用
ClassA
的实例调用,但函数需要子类的实例作为参数。(它只会反过来工作。)这很有趣,因为我曾经尝试过一个例子,将返回类型作为一个子类,正如您所说的,编译器并没有抱怨。这个例子很清楚地说明了为什么,因为设置“subclass tonil”不会更改functionVariable的类型签名!