我不确定哪个 where
子句可以将泛型参数限制为从某个协议(protocol)继承的协议(protocol)。
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...
有什么方法可以限制 eatAnything()
允许协议(protocol)类型,但仅限那些继承自 Edible
的协议(protocol)类型?
最佳答案
在您的示例中,泛型函数的定义没有任何意义,因为它可以替换为:
func eat(_ item: Edible) -> String {
return "Just ate some \(type(of: item))"
}
但是如果你真的想使用泛型函数那么你应该知道:
泛型函数的定义
-
func eat<T: Edible>(_ item: T) -> String { ... }
-
func eat<T>(_ item: T) -> String where T: Edible { ... }
-
func eat<T: Edible>(_ item: T) -> String where T: Equatable { ... }
-
协议(protocol)是动态类型,因此它们使用后期绑定(bind)。通用代码在编译期间被转换为普通代码,需要早期绑定(bind)
- 早期绑定(bind) (编译时):类型在运行时运行变量之前已知,通常通过静态的声明方式
- 后期绑定(bind) (运行时):在运行时执行变量之前,类型是未知的;通常通过赋值,但还有其他方法来强制类型;动态类型语言将此称为底层功能
通用函数可以定义为与协议(protocol)兼容的类型,但此函数不能将此协议(protocol)作为类型传递,因为编译器不知道该类型是什么
T
.传递给泛型函数的类型必须是特定类型(类、结构、枚举……)
let a: [Int] = [1,2,3]
let b: [CustomStringConvertible] = [1, "XYZ"]
a.index(of: 2) // 1
b.index(of: "XYZ") // error
关于swift - 将通用参数限制为从协议(protocol)继承的协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46260511/