2016-02-27 95 views
1

有沒有辦法給函數賦一個參數,該參數是函數變量的子類,參數是它的超類?這裏是我的意思的一個例子:函數類型中的swift子類

class ClassA {} 

class subclassOfA:ClassA {} 

func subclassToNil(argument:subclassOfA) ->(){} 

var functionVariable:(ClassA->()) 

funcVar = subclassToNil 

這引發了一個類型不兼容異常。

+1

這是行不通的。 'functionVariable()'可以用'ClassA'的一個實例調用,但是該函數需要一個* subclass *的實例作爲參數。 (它只會反過來工作。) –

回答

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. 

所以它的安全使用是具體參數。返回值的推理非常相似,從邏輯上看,您可以使用更多特定的

+0

這很有趣,因爲我已經嘗試了一個返回類型作爲子類的例子,正如你所說的,編譯器沒有抱怨。這個例子很清楚爲什麼因爲設置'subclassToNil'不會改變functionVariable的類型簽名! – chartman