Это работает:
protocol Walkable {
init()
}
class Animal {
init(someProperty: Int) {}
}
class WalkableAnimal: Animal, Walkable {
required init() {
super.init(someProperty: 0)
}
}
class Person {
init() {
InitializeAWalkableAnimal(walkableAnimal: WalkableAnimal.self)
}
func InitializeAWalkableAnimal<T: Animal>(walkableAnimal: T.Type) where T: Walkable {
let animal = walkableAnimal.init()
}
}
Однако я хочу полностью отказаться от подкласса WalkableAnimal.Я просто хочу создать Cat
class
, который наследуется от Animal
и соответствует протоколу Walkable
.Кроме того, я не могу передать Cat
напрямую в качестве параметра, потому что типы являются динамическими.Я ожидаю, что что-то вроде этого должно работать:
protocol Walkable {
init()
}
class Animal {
init(someProperty: Int) {}
}
class Cat: Animal, Walkable {
required init() {
super.init(someProperty: 0)
}
}
class Dog: Animal, Walkable {
required init() {
super.init(someProperty: 1)
}
}
typealias AnyWalkableAnimal = (Animal & Walkable).Type
class Person {
init(anyWalkableAnimal: AnyWalkableAnimal) {
// ERROR
InitializeAWalkableAnimal(walkableAnimal: anyWalkableAnimal.self)
}
func InitializeAWalkableAnimal<T: Animal>(walkableAnimal: T.Type) where T: Walkable {
let animal = walkableAnimal.init()
}
}
class PersonCaller {
init() {
Person(anyWalkableAnimal: Cat.self)
Person(anyWalkableAnimal: Dog.self)
}
}
Ошибка:
Метод экземпляра 'InitializeAWalkableAnimal (walkableAnimal :)' требует, чтобы 'Animal' соответствовал 'Walkable'
Это нонсенс, поскольку typealias
не допускает типы, которые не Walkables
, верно?Почему компилятор не счастлив?Можно ли как-нибудь обойти любой тип, который соответствует Animal
и Walkable
?Почему typealias
не работает?typealias
прямо указывает, что тип, который он принимает, должен быть Animal
и Walkable
.Это работает наоборот (как и ожидалось): когда я пытаюсь передать Animal
, который не соответствует Walkable
, инициализатор выдает ошибку компиляции.
Я занимаюсь разработкой Swift Development Toolchain 25 декабря 2018 года, если это что-то изменит.