如果 Swift 泛型类型约束是一个协议(protocol)名称,我可以要求受该协议(protocol)约束的两个类型是同一类型。例如:
protocol Flier {}
struct Bird : Flier {}
struct Insect: Flier {}
func flockTwoTogether<T:Flier>(f1:T, f2:T) {}
flockTwoTogether
函数可以用鸟和鸟或昆虫和昆虫调用,但不能用鸟和昆虫调用。这就是我想要的限制。到目前为止,还不错。
但是,如果我用类名尝试同样的事情,它不起作用:
class Dog {}
class NoisyDog : Dog {}
class WellBehavedDog: Dog {}
func walkTwoTogether<T:Dog>(d1:T, d2:T) {}
问题是我可以用 WellBehavedDog 和 NoisyDog 调用 walkTwoTogether
。这就是我要防止的。
这里确实有两个问题:
有没有办法说明不能用 WellBehavedDog 和 NoisyDog 调用
walkTwoTogether
?这是一个错误吗?我问是因为如果我不能使用泛型来表达这一点,就很难理解为什么泛型约束作为类名是有用的,因为我们可以用普通函数得到相同的结果。
最佳答案
本身不是答案,但可能还有更多数据......问题是当你打电话时:
walkTwoTogether(NoisyDog(), WellBehavedDog())
Swift 可以将这两个实例视为 Dog
的实例(又名,upcast)——我们需要它,以便我们可以调用类 A
的方法A
的子类。 (我知道你知道这一点。)
Swift 不会向上转换为协议(protocol),因此唯一的方法是为父类(super class)不符合的子类指定一个协议(protocol):
protocol Walkable {}
extension NoisyDog : Walkable {}
extension WellBehavedDog: Walkable {}
func walkTwoTogether<T: Dog where T: Walkable>(d1:T, d2:T) { }
walkTwoTogether(NoisyDog(), WellBehavedDog())
// error: type 'Dog' does not conform to protocol 'Walkable'
错误消息明确显示了正在发生的事情 — 调用此版本的 walkToTogether
的唯一方法是将子类实例向上转换为 Dog
,但是 Dog
不符合 Walkable
。
关于generics - 如何在 Swift 泛型中说 "same class",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27323165/