Могу ли я привести объект метакласса к типу протокола в Swift?
Swift унаследовал концепцию метакласса Objective-C: сами классы также считаются объектами. КлассFoo
Класс объектаFoo.self
и это типаFoo.Type
, ЕслиFoo
наследует отBar
, затемFoo.self
может быть назначен переменной типаBar.Type
, тоже. Это имеет как минимум два преимущества:
Особенно сейчас я смотрю на второй. Просто чтобы быть уверенным, что все понимают, чего я добиваюсь, вот пример:
class BaseFoo {
var description: String { return "BaseFoo" }
}
class DerivedFoo: BaseFoo {
override var description: String { return "DerivedFoo" }
}
let fooTypes: [BaseFoo.Type] = [BaseFoo.self, DerivedFoo.self] // metaclass magic!
for type in fooTypes {
let object: BaseFoo = type() // metaclass magic!
println(object)
}
Теперь у меня есть массивAnyClass
объекты (любой экземпляр метакласса может быть назначенAnyClass
так же, как любой объект может быть назначенAnyObject
), и я хочу найти, какие из них реализуют данный протокол. Протокол объявляет инициализатор, и я создаю экземпляр класса так же, как и в примере выше. Например:
protocol Foo {
init(foo: String)
}
class Bar: Foo {
required init(foo: String) { println("Bar initialized with \(foo)") }
}
class Baz {
required init() { println("I'm not a Foo!") }
}
let types: [AnyClass] = [Bar.self, Baz.self]
Все идет нормально. Теперь проблема заключается в определении, реализует ли класс протокол. Поскольку экземпляры метакласса полиморфны, я ожидаю, что смогу их привести. Тем не менее, я явно что-то упускаю, потому что Свифт не позволит мне написать это:
for type in types {
if let fooType = type as? Foo.Type {
let obj = fooType(foo: "special snowflake string")
}
}
Я получаю ошибку компилятора:
ошибка: 'Foo' не идентичен 'AnyObject'
Есть ли способ определить, представляет ли экземпляр метакласса класс, реализующий протокол, и есть ли способ преобразовать этот экземпляр в тип протокола?
Я пытался объявитьFoo
как протокол класса, но этого явно недостаточно.
РЕДАКТИРОВАТЬ: Я только что попробовал сAny
типа, и хотя это не вызывает синтаксическую ошибку, он приводит к сбою компилятора Swift.