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)
}
...
}
并且没有任何问题
我正在尝试创建一个将闭包作为参数的通用函数。不过我遇到了问题,所以为了隔离问题,我创建了以下代码,可以在操场上 运行。
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)
}
...
}
并且没有任何问题