Reputation: 902
I want to make a generic function which takes a generic array as a parameter. I have two classes Animal and Bird as well as two protocols Animals & Birds and my method parameter conforms to these two protocols but I am not able to add to the array.
protocol Birds {
var canFly: Bool {get set}
}
protocol Animals {
var name: String {get set}
var legs: Int {get set}
}
class Animal: Animals {
var name: String
var legs: Int
init(name: String, legs: Int) {
self.name = name
self.legs = legs
}
}
class Bird: Birds {
var canFly: Bool
init(canFly: Bool) {
self.canFly = canFly
}
}
func myTestGenericMethod<T>(array: [T]) where T: Animals & Birds {
for (index, _) in array.enumerated() {
print("At last i am able to get both Animal and Bird")
}
}
let cat = Animal(name: "cat", legs: 4)
let dog = Animal(name: "dog", legs: 4)
let crow = Bird(canFly: true)
myTestGenericMethod(array: [dog])
myTestGenericMethod(array: [cat, dog]) // Not Able to add this to array
Upvotes: 2
Views: 3839
Reputation: 12154
When you write where T: Animals & Birds
, T
must be extended from Animals
AND Birds
But cat
and dog
aren't extended from both Animals
AND Birds
. So this is problem.
As I understand, you want T
have to be extended from Animals
OR Birds
. To do it, we must have a base protocol which both Animals
and Birds
are extended from. Change a little code and fix it.
@objc protocol Base {
}
protocol Birds : Base {
var canFly: Bool {get set}
}
protocol Animals : Base {
var name: String {get set}
var legs: Int {get set}
}
class Animal: Animals {
var name: String
var legs: Int
init(name: String, legs: Int) {
self.name = name
self.legs = legs
}
}
class Bird: Birds {
var canFly: Bool
init(canFly: Bool) {
self.canFly = canFly
}
}
func myTestGenericMethod<T: Base>(array: [T]) {
for object in array {
if object is Bird {
let bird = object as! Bird
print(bird.canFly)
} else if object is Animal {
let animal = object as! Animal
print(animal.name)
}
}
}
let cat = Animal(name: "cat", legs: 4)
let dog = Animal(name: "dog", legs: 4)
let crow = Bird(canFly: true)
myTestGenericMethod(array: [crow, cat, dog] as! [Base])
myTestGenericMethod(array: [cat, dog])
Upvotes: 2
Reputation: 5954
In your code where T: Animals & Birds
means that you require T
to be an instance conforming to both protocols at the same time. But you don’t have a class conforming to both protocols. If you create one then you’ll be able to use its instances in your generic method.
Upvotes: 1