这两种声明泛型超类的方法之间的区别是什么?有'其中'条款?
func foo<T: SomeClass>(object: T) -> Array<T>
func foo<T>(object: T) -> Array<T> where T: SomeClass
答案 0 :(得分:7)
泛型where子句中的要求指定了一个类型 参数继承自类或符合协议或协议 组成。虽然泛型where子句提供了句法 用于表达类型参数的简单约束的糖(用于 例如,
<T: Comparable>
相当于<T> where T: Comparable
和 等等),您可以使用它来提供更复杂的类型约束 参数及其相关类型。例如,你可以约束 符合协议的相关类型参数类型。对于 例如,<S: Sequence> where S.Iterator.Element: Equatable
指定S
符合Sequence
协议以及相关类型S.Iterator.Element
符合Equatable
协议。这个约束 确保序列中的每个元素都是等同的。
简单地说,where
允许您指定关于通用参数的关联类型的约束,而在<>
中则无法执行此操作。
答案 1 :(得分:1)
这些问题总是需要一些实际的例子,即使是最简单的基本想法。否则它通常仍然是理论上的。
由Sweeper引用,在where
之后的那个被称为类型约束。通常,您指定一个或多个协议,这些协议引入了传递的对象或类型必须满足的条件。如上所述,只有在where
之后才可以指定泛型类型的associatedtype
约束。
考虑以下示例:
protocol MyProtocol {
associatedtype AType
func foo()
}
class MyClassInt : NSObject, MyProtocol {
typealias AType = Int
func foo() {
print(type(of: self))
}
}
class MyClassString : NSObject, MyProtocol {
typealias AType = String
func foo() {
print("I'm not implemented")
}
}
extension MyProtocol where Self.AType == Int {
func test() {
self.foo()
}
}
现在检查我们的东西:
let str = MyClassString()
str.test() // Won't compile !!
'MyClassString.AType'(又名'String')不能转换为'Int'
这个编译并运行:
let int = MyClassInt()
int.test()
在这个例子中,我们有一个指定了associatedtype
的协议。还有一个extension
仅适用于我们的MyProtocol
,特别是associatedtype
,在我们的案例Int
中。该扩展定义了单一方法。正如您所看到的,即使associatedtype
也实现了该协议,编译器也不会让我们使用除MyClassString
以外的<link rel="stylesheet" href="Untitled-2.css" type="tex/css">
来调用该方法。