Я хочу иметь статический метод базового класса, который возвращает массив типа подкласса. Вот моя текущая реализация. Это работает, но у меня есть небольшая проблема с ним.
class Animal {
required init() { }
public static func generateMocks<T: Animal>() -> [T] {
var mocks: [T] = []
// some implementation goes here...
for _ in 0..<10 {
mocks.append( T() )
}
//
return mocks
}
}
let myMockAnimals: [Animal] = Animal.generateMocks() // this gives me type [Animal]
class Dog: Animal {
// dog things
var isCute = true
}
let myMockDogs: [Dog] = Dog.generateMocks() // this gives me type [Dog]
print(myMockDogs.first?.isCute) // true
/* My problem is that it is very annoying to have to declare my
myMockDogs variable as type "[Dog]". I would like it to
automatically infer this type. Like this: */
let myMockDogs2 = Dog.generateMocks() // oh no! It gives me type [Animal]
print(myMockDogs2.first?.isCute) // error! Value of type 'Animal' has no member 'isCute'
if let dog = myMockDogs2.first! as Dog { // error! 'Animal' is not convertible to 'Dog';
print(dog)
}
Так что моя общая статическая функция generateMocks
способна вернуть правильный подкласс, когда я указываю ожидаемый тип объекта, например let myMockDogs2: [Dog] =...
, но когда я отбрасываю явный тип, который я ожидаю, как в let myMockDogs2 =...
, он внезапно возвращается к использованию Animal
в качестве типа, используемого для универсальной функции, в результате чего получается массив [Animal]
.
Есть ли способ изменить функцию generateMocks
, которая заставит let myMockDogs2 = Dog.generateMocks()
автоматически использовать тип Dog
для общего T
?
Вы можете скопировать этот код в игровую площадкуслишком! Это работает там! Я действительно боюсь, что нет решения, но, возможно, у гения Свифта есть идея.