我在尝试将Self
作为协议一部分的泛型函数中的where
子句的一部分时遇到问题。在泛型函数中使用Self时出错,其中子句
例如,说我有这个协议和这个定义泛型函数:
protocol Animal {
associatedtype FoodSource
func eat(_ food:FoodSource)
}
// The where clause specifies that T2 must conform to
// whatever type is T1's FoodSource associated type
func feed<T1: Animal, T2>(animal:T1, food:T2) where T2 == T1.FoodSource {
animal.eat(food)
}
功能饲料使用括号内的语句声明的是,第一个参数必须符合Animal
协议。它使用where
子句声明第二个参数的类型必须符合第一个参数的关联类型。
有可能创建符合这个通用函数的要求的类,并且一切都很完美。例如:
protocol Meat {}
protocol Vegetable {}
class Rabbit : Animal {
typealias FoodSource = Vegetable
func eat(_ food:FoodSource) {
print("the Rabbit ate the \(type(of:food))")
}
}
class Lion : Animal {
typealias FoodSource = Meat
func eat(_ food:FoodSource) {
print("the Lion ate the \(type(of:food))")
}
}
class Carrot : Vegetable {}
class Steak : Meat {}
class ChickenSalad : Meat, Vegetable {}
// works because Carrot conforms to Vegetable
// prints: "the Rabbit ate the Carrot"
feed(animal: Rabbit(), food: Carrot())
// works because Steak conforms to Meat
// prints: "the Lion ate the Steak"
feed(animal: Lion(), food: Steak())
// works because ChickenSalad conforms to Meat
// prints: "the Lion ate the ChickenSalad"
feed(animal: Lion(), food: ChickenSalad())
// works because ChickenSalad conforms to Vegetable
// prints: "the Rabbit ate the ChickenSalad"
feed(animal: Rabbit(), food: ChickenSalad())
到目前为止这么好。
然而,当我实现仿制药相同的模式作为协议的一部分,它不再起作用:
protocol Food {
func feed<T:Animal>(to:T) where Self == T.FoodSource
}
extension Food {
func feed<T:Animal>(to animal:T) where Self == T.FoodSource {
animal.eat(self)
}
}
class SteakSalad : Food, Meat, Vegetable {}
SteakSalad().feed(to: Lion())
执行时,该块将引发以下错误:
error: generic parameter 'T' could not be inferred
SteakSalad().feed(to: Lion())
^
是有一些方法可以达到理想的行为?
https://stackoverflow.com/questions/36810270/swift-protocols-with-associated-type-requirement-and-default-implementation – suhit
也许我很厚,但我不确定这究竟是如何适用于我案件。我知道所提供的例子在内容方面非常相似,但它似乎是一个单独的问题。在链接帖子的情况下,类型推断不再适用于'Cow',因为如果没有该方法签名,就不能确定Cow.Food的关联类型。在我的例子中,我不明白为什么不直接从提供的参数(在这种情况下是'Lion')推断出类型。 – sak