当在函数签名中指定模式时,特殊的多态性/函数重载在Swift中不起作用



我在Swift 2.2和2.3中有一些多态性问题。我正在与NSManagedObjects合作,并建立特定的视图。我注意到我的视图生成器没有根据模型的子类调用正确的重载函数。

在游乐场里,我弄乱了一些东西,发现了以下内容:

import Foundation
class DataObject: NSObject {}
class X: DataObject {}
class Y: DataObject {}
class ViewBuilder {
    func viewForModel<S where S: DataObject>(model: S) {
        tmp(model)
    }
    func tmp(model: X) {
        print("X")
    }
    func tmp(model: Y) {
        print("Y")
    }
    func tmp(model: DataObject) {
        print("Base")
    }
}
ViewBuilder().viewForModel(X())

尽管传递了类型x,但仍打印出"Base"。我错过了什么吗?为什么它调用基类tmp()函数,而不是一个适当的子类?

这里的子类问题很有趣,但我想知道您是否会更好地使用这样的东西:

class ViewBuilder {
    func viewForModel(model: X) {
        print("X")
    }
    func viewForModel(model: Y) {
        print("Y")
    }
    func viewForModel(model: DataObject) {
        print("Base")
    }
}

这会产生期望的结果:

ViewBuilder().viewForModel(X())打印"X"

ViewBuilder().viewForModel(Y())打印"Y"

如果您的class Z: DataObject {}没有特定的方法:

ViewBuilder().viewForModel(Z())打印"Base"

问题是X首先是DataObject,你必须像这样转换到子类:

func viewForModel<S where S: DataObject>(model: S) {
    model.dynamicType
    tmp(model as! X)
}

最新更新