我将我的麻烦简化为一个关于使用Generic Type和protocol的小型演示。这是代码。
protocol Food {
}
class Meat: Food {
}
class Cake: Food {
}
protocol EatProtocol {
func eat<T: Food>(_: T)
}
class Person: EatProtocol {
func eat<T>(_: T) where T : Food {
print("eat food")
}
}
class Man: Person {
override func eat<T>(_: T) where T : Meat {
print("eat meat")
}
}
class Woman: Person {
override func eat<T>(_: T) where T : Cake {
print("eat cake")
}
}
let man = Man()
let woman = Woman()
let manyPeople: [EatProtocol] = [man, woman]
let meat = Meat()
let cake = Cake()
let manyFood: [Food] = [meat, cake]
for (index, people) in manyPeople.enumerated() {
let food = manyFood[index]
people.eat(food)//error: Cannot invoke 'eat' with an argument list of type '(Food)'
}
问题是我确信for循环项目得到正确的食物,但编译器给我错误
答案 0 :(得分:1)
这里有一个根本问题:并非所有食客都可以吃各种食物。在这个特定示例中,我能想到的最好的方法是使用switch
来枚举可能的组合,安全地投射并进行调用:
protocol Food {}
class Meat: Food {}
class Cake: Food {}
protocol Eater {
func eat<T: Food>(_: T)
}
class Person: Eater {
func eat<T>(_: T) where T: Food {
print("eat food")
}
}
class Man: Person {
override func eat<T>(_: T) where T: Meat {
print("eat meat")
}
}
class Woman: Person {
override func eat<T>(_: T) where T : Cake {
print("eat cake")
}
}
let eaters: [Eater] = [Man(), Woman()]
let foods: [Food] = [Cake(), Cake()]
for (food, eater) in zip(foods, eaters) {
switch (food, eater) {
case let (meat as Meat, man as Man): man.eat(meat)
case let (cake as Cake, woman as Woman): woman.eat(cake)
//...
default:
print("\(eater) (of type: \(type(of: eater))) cannot eat \(food) (of type: \(type(of: food)))")
continue
}
}