Swift 将泛型参数限制为从协议继承的协议

Swift 将泛型参数限制为从协议继承的协议,swift,generics,inheritance,protocols,Swift,Generics,Inheritance,Protocols,我不确定什么where子句可以将泛型参数限制为从某个协议继承的协议 protocol Edible {} protocol PetFood: Edible {} struct CatFood: PetFood {} struct Rocks {} func eat<T: Edible>(_ item: T) -> String { return "Just ate some \(type(of: item))" } let food: CatFood = CatFo

我不确定什么
where
子句可以将泛型参数限制为从某个协议继承的协议

protocol Edible {}
protocol PetFood: Edible {}
struct CatFood: PetFood {}
struct Rocks {}

func eat<T: Edible>(_ item: T) -> String {
    return "Just ate some \(type(of: item))"
}

let food: CatFood = CatFood()
eat(food) //"Just ate some CatFood"

let moreFood: PetFood = CatFood()
//eat(moreFood) //Cannot invoke 'eat' with an argument list of type '(PetFood)'

func eatAnything<T>(_ item: T) -> String {
    return "Just ate some \(type(of: item))"
}

eatAnything(moreFood) //This works, obviously
eatAnything(Rocks()) //But, of course, so does this...
protocol{}
宠物食品:可食用{}
结构猫粮:宠物食品{}
构造岩{}
func eat(u-item:T)->字符串{
return“刚吃了一些\(类型:项目))”
}
让食物:猫粮=猫粮
吃(食物)/“吃点猫粮”
let moreFood:PetFood=CatFood()
//eat(moreFood)//无法使用类型为“(PetFood)”的参数列表调用“eat”
func eatAnything(uItem:T)->字符串{
return“刚吃了一些\(类型:项目))”
}
吃任何东西(更多的食物)//显然,这是有效的
eatAnything(Rocks())//但是,当然,这个也是。。。

是否有任何方法限制
eatAnything()
允许协议类型,但仅允许从
eable
继承的协议类型?

在您的示例中,泛型函数的定义没有任何意义,因为它可以替换为:

func eat(_ item: Edible) -> String {
    return "Just ate some \(type(of: item))"
}
但如果您真的想使用泛型函数,那么您应该知道:

  • 泛型函数的定义

    • func-eat(uitem:T)->String{…}
    • func eat(uitem:T)->字符串,其中T:aubible{…}
    • func-eat(uitem:T)->字符串,其中T:equalable{…}
  • 协议是动态类型,因此它们使用后期绑定。泛型代码在编译期间转换为普通代码,需要提前绑定

    • 早期绑定(编译时):在运行时执行变量之前,类型是已知的,通常通过静态声明方式
    • 后期绑定(运行时):在运行时执行变量之前,类型未知;通常通过赋值,但有其他方法强制类型;动态类型语言称之为底层特性
  • 泛型函数可以定义为与协议兼容的类型,但此函数不能将此协议作为类型传递,因为编译器不知道该类型是什么
    t
    。传递给泛型函数类型必须是特定类型(类、结构、枚举等)


  • 当然,这只是一个简单的例子来说明这个问题。
    let a: [Int] = [1,2,3]
    let b: [CustomStringConvertible] = [1, "XYZ"]
    
    a.index(of: 2) // 1
    b.index(of: "XYZ") // error