Swift 使用带有闭包的泛型函数时创建错误类型的实例

Swift creates instance of wrong type when using a generic function with a closure

我正在尝试创建一个将闭包作为参数的通用函数。不过我遇到了问题,所以为了隔离问题,我创建了以下代码,可以在操场上 运行。

class BaseClass {
    init(message: String) {
        println("Base class says: " + message)
    }

    func getMyName() -> String {
        return "BaseClass"
    }
}

class SubClass: BaseClass {
    override init(message: String) {
        println("Subclass says: " + message)
        super.init(message: message)
    }

    override func getMyName() -> String {
        return "SubClass"
    }

    func specialAbility() {
        println("only I can do this!")
    }
}

func makeInstance<T: BaseClass>(callback: (T -> Void)?) {
    callback?(T(message: "hello"))
}

makeInstance() {
    (instance: SubClass) in
    println("makeInstance1 built a " + instance.getMyName())
    println("I think it is a \(_stdlib_getDemangledTypeName(instance))")

    //instance.specialAbility() - uncommenting this throws EXC_BAD_ACCESS at runtime
}

makeInstance() {
    (instance: BaseClass) in
    println("makeInstance2 built a " + instance.getMyName())
    println("I think it is a \(_stdlib_getDemangledTypeName(instance))")
}

此代码产生以下输出:

Base class says: hello
makeInstance1 built a BaseClass
I think it is a __lldb_expr_89.SubClass
Base class says: hello
makeInstance2 built a BaseClass
I think it is a __lldb_expr_89.BaseClass

Swift 不允许您在函数调用中显式指定类型(例如 makeInstance),因此我希望编译器从调用中的闭包类型推断出它。它似乎每次都创建一个 BaseClass 实例。未调用 SubClass 初始化程序,其成员似乎是 BaseClass 的成员。

我敢说这似乎是 Swift 中的一个错误;如果您尝试在第一个闭包中访问 SubClass 的成员,编译器没有问题,但在 运行 时,会抛出异常(请参阅我在代码中的注释)。

有什么办法可以解决这个问题吗?如果不清楚,我想在闭包需要一个时创建一个BaseClass的子类。

实际上我只是将你的初始值设定项更改为 required 如下:

class BaseClass {
    required init(message: String) {
        println("Base class says: " + message)
    }

    func getMyName() -> String {
        return "BaseClass"
    }
}

class SubClass: BaseClass {
    required init(message: String) {
        println("Subclass says: " + message)
        super.init(message: message)
    }
    ...
 }

并且没有任何问题