Создавать объект типа Generic в Swift

Я реализую класс Foo в Swift, который должен создавать объекты данного подкласса SuperBar, например. Bar: SuperBar. Мне очень нравятся generics в Swift, поэтому я попытался реализовать его так:

class Foo<T: SuperBar> {

    func instantiateObject() -> T {
        return T()
    }

}

class SuperBar {

}

class Bar: SuperBar {

}

let foo = Foo<Bar>()

let obj = foo.instantiateObject()

Вы можете запустить фрагмент кода на игровой площадке Xcode и заметить, что obj имеет тип SuperBar вместо Bar, хотя он говорит Bar, когда я Alt -click на имени константы.

Любые идеи?:)

Ответ 1

Если вы добавите required init() { } в SuperBar, он будет работать правильно. Это требование всегда должно быть обязательным в любом случае, потому что вы создаете экземпляр из класса переменных.

Тот факт, что он позволяет вам создать его с помощью инициализатора, который не требуется, является ошибкой.

Ответ 2

Отметьте класс init как required, а затем вызовите init:

class SuperBar {
    required init() {
    }
}


class Foo<T: SuperBar> {

    func instantiateObject() -> T {
        return T.init()
    }

} 

Ответ 3

Вы можете заставить его бросить, если вы точно знаете тип родового.

let emptyObject:T = NSObject() as! T

Очевидно, что это побеждает цель универсального класса, но может быть полезно для некоторых значений по умолчанию или функциональности базового класса, как это было в моем случае.

Это также опасно и сбой, если тип T не NSObject