generics - 如何在 Swift 泛型中说 "same class"

标签 generics swift

如果 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/

相关文章:

c# - 为什么我不能强制派生类具有无参数构造函数?

go - 函数类型不能有类型参数

ios - 将对象存储到 RealmSwift 中的列表后的 EXC_BAD_ACCESS

ios - 在导航 Controller 上推送的 viewController 中实现 MapKit 的有效方法?

c# - 在方法中传递和返回两个不同的泛型类

swift - 定义在闭包中使用的泛型类型

ios - 我正在使用 swift 构建一个船舶游戏。无法检测碰撞

ios - '? :' 表达式中的结果值具有不匹配的类型 '()' 和 'Bool'

java - 数组声明和集合声明有什么区别

ios - 如何同时翻转和旋转标签?