Я пытаюсь создать общую функцию, которая принимает закрытие в качестве параметра. У меня проблема, поэтому, чтобы изолировать проблему, я создал следующий код, который можно запустить на игровой площадке.Swift создает экземпляр неправильного типа при использовании общей функции с закрытием
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, когда его ожидает.
На самом деле, более играя вокруг показал, что закрытие не имеет ничего общего с ним. Проблему можно увидеть, как это тоже (извините за плохое форматирование): 'FUNC makeInstance() -> T { возврата T (сообщение: "привет") } пусть инст: SubClass = makeInstance() println ("makeInstance() make (inst.getMyName())") // показывает BaseClass' Я думаю, что проблема связана с этой проблемой (http://stackoverflow.com/questions/ 27117921/неспособный к вызову-initializer-for-subclass-of-generic-type), однако я не могу заставить это решение работать для меня здесь. –