如何在 Swift 泛型中说“同一类”

2024-06-19

如果 Swift 泛型类型约束是协议名称,我可以要求受该协议约束的两种类型为同一类型。例如:

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) {}

问题是我可以打电话walkTwoTogether与一只行为良好的狗和一只吵闹的狗。这就是我想要阻止的。

这里确实有两个问题:

  • 有没有办法这么说walkTwoTogether不能用 WellBehavedDog 和 NoisyDog 来调用吗?

  • 这是一个错误吗?我之所以这么问,是因为如果我不能使用泛型来表达这一点,就很难理解为什么泛型约束作为类名是有用的,因为我们只需使用普通函数就可以得到相同的结果。


本身不是答案,但也许还有更多数据......问题是当你打电话时:

walkTwoTogether(NoisyDog(), WellBehavedDog())

Swift 可以将这两个实例视为Dog(又名,upcast)——我们需要它,这样我们就可以调用类的方法A与子类A。 (我知道你知道这一点。)

Swift 不会向上转换为协议,因此唯一的方法是为超类的子类指定一个协议doesn't符合:

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, but Dog不符合Walkable.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Swift 泛型中说“同一类” 的相关文章

随机推荐