【问题标题】:Swift generic T.Type becomes T.ProtocolSwift 泛型 T.Type 变为 T.Protocol
【发布时间】:2020-08-20 18:10:27
【问题描述】:

斯威夫特 5.1

我正在编写一个具有泛型参数T 的类,它的一个方法接受一个类型作为参数,其中类型从T.Type 扩展。请参阅下面的foo1

public protocol P {
}

public class C: P {
}

public class X<T> {
    public func foo1(_ t: T.Type) { // The function in question
    }

    public func foo2(_ t: P.Type) {  // Note that this works as expected, but is not generic
    }
}

public func test() {
    let x = X<P>()
    x.foo1(C.self) // ERROR Cannot convert value of type 'C.Type' to expected argument type 'P.Protocol'
    x.foo2(C.self) // Works as expected, but is not generic
}

现在,当 T 是一个类时,foo1 可以正常工作。但是,当T 是协议时(例如P),Swift 似乎将我的函数签名从T.Type 重写为T.Protocol

  1. 为什么要这样做?
  2. 如何让foo1 接受从P 继承的类型?

X 用于许多其他地方 - 对其的任何更改都不得限制或删除类参数 T 或减少 X 的功能,也不得明确引用 C 或 @987654337 @。 (约束T 以排除不扩展AnyObject 的协议是可以接受的;不过,我不知道该怎么做。例如,创建X 的子类添加能够处理T 中的协议,但我也不知道该怎么做。)

为了清楚起见,出于更复杂的项目原因,此类用于注册符合某些指定父级 (T) 的类 (t)。 (请注意,正在注册类,而不是其实例。)父级在创建X 时通过 type 参数给出。它适用于任何类的T,但我也希望它适用于任何协议的T - 或至少适用于任何协议P: AnyObjectT,在这种情况下@987654349 @ 应该接受 P 的任何子类...与 T 是类时的工作方式相同。

【问题讨论】:

  • 如果你写 let x = X() x.foo1(C.self) // OK x.foo2(C.self)
  • func foo1&lt;T&gt;(_ t: T.Type) where T: P {
  • @jawadAli 好吧,因为我还希望foo1(C2.self)X 的同一个实例工作,其中C2: P
  • @LeoDabus 抱歉,我试图列出所有约束,但我想虽然我指定 C 不能在 X 中显式使用,但我没想到要指定 P无法明确使用。我已经更新了我的问题。

标签: swift generics inheritance


【解决方案1】:

虽然C是一个P,但是C.Type != P.Type,所以报错。

但泛型的工作方式有点不同,如下例所示:

public class X {
    public func foo1<T>(_ t: T.Type) { // this way
    }

    public func foo3<T:P>(_ t: T.Type) { // or this way
    }

    public func foo2(_ t: P.Type) {  // Note that this works as expected, but is not generic
    }
}

public func test() {
    let x = X()
    x.foo1(C.self) // << works
    x.foo3(C.self) // << works
    x.foo2(C.self) // Works as expected, but is not generic
}

【讨论】:

  • 我不确定我是否理解您的第一行 - 相反,CPC.TypeP.Type,但 C.Type 不是 P.Protocol ,并且由于某种原因,Swift 正在进行第三次检查而不是第二次检查。不幸的是,我宁愿不从类中删除泛型参数,因为 X 旨在与所有类的 子集 一起使用(该子集在 X 的实例化时指定) .如果我摆脱类的泛型参数,我会失去很多类型安全。我在问题的末尾添加了一个解释,这可能更清楚。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-29
  • 2020-04-21
  • 1970-01-01
  • 1970-01-01
  • 2018-02-20
  • 1970-01-01
相关资源
最近更新 更多