Sorry for the basic question. I am working through the Head First Swift book and have hit a snag. I am trying to iterate over an array of custom types and access the functions of the Dog and Cat types in a for in loop but I can't figure out the syntax. How do I call either bark() or meow() depending on whether the item in the array is a Dog or Cat?
protocol Animal {
var type: String { get }
}
struct Dog: Animal {
var name: String
var type: String
func bark() {
print("Woof woof")
}
}
struct Cat: Animal {
var name: String
var type: String
func meow() {
print("Meow")
}
}
var bunty = Cat(name: "Bunty", type: "British Shorthair")
var nigel = Cat(name: "Nigel", type: "Russian Blue")
var percy = Cat(name: "Percy", type: "Manx")
var argos = Dog(name: "Argos", type: "Whippet")
var barny = Dog(name: "Barny", type: "Bulldog")
var animals: [Animal] = [bunty, nigel, percy, argos, barny]
print(animals.count)
for animal in animals {
}
I have tried an if statement in the loop:
for animal in animals {
if animal == Cat {
meow()
} else {
bark()
}
}
But Swift says "Binary operator == cannot be applied to operands Animal and Cat.type. Thanks for your help, I'm trying to learn.
CodePudding user response:
Since protocol Animal declare only property var type: String { get }
and you want to call functions bark()
and meow()
which are only visible to their specific types you will have to downcast with as?
operator.
for animal in animals {
if let dog = animal as? Dog {
dog.bark()
}
if let cat = animal as? Cat {
cat.meow()
}
}
CodePudding user response:
Michal Olechowski is right that you need to downcast in order to call those methods. Here are two additional ways that can be done:
Use switch
to identify the class
for animal in animals {
switch animal {
case let dog as Dog:
dog.bark()
case let cat as Cat:
cat.meow()
default: break
}
}
Use optional chaining with downcasting
for animal in animals {
(animal as? Dog)?.bark()
(animal as? Cat)?.meow()
}
In this case, if the conditional downcast works then the optional value is unwrapped and the method is called. If the conditional downcast fails and returns nil
, then nothing happens.