【问题标题】:Subclassing generic class in Swift fails在 Swift 中继承泛型类失败
【发布时间】:2017-03-10 06:15:22
【问题描述】:

我对泛型编程相当陌生,并且在使用 Swift 3 和子类化泛型类时遇到了问题。我已将其简化为一个失败的简单案例,希望有人能帮助解释我为什么会失败。

使用以下协议和类,一切正常。这行得通(我的真实代码还有很多工作要做,但工作正常):

protocol P {
  associatedtype T
}

class Temp<X> {}
class C1<D:P> {
  init(tmp: Temp<D.T>) {}
}

但是,当我按如下方式进行子类化时:

class C2<L:P> : C1<L> {}

我得到这个编译器失败:

<unknown>:0: error: expression type 'Temp<_>' is ambiguous without more context

错误不在特定行上,而是出现在编译器活动日志中的故障。

也许我缺少一些简单的东西,但我只是看不到它。我的子类与基类具有相同的约束(即它必须采用协议 P),所以在我看来这应该可行。

有什么想法吗?

【问题讨论】:

  • 看起来问题出在其他地方。这个问题中包含的代码编译没有问题(使用 Swift 3.1)。您可能在 Temp 实例的泛型类型 X 与预期类型 D.T 之间不匹配,或者您在 C1C2 的实例化时未指定泛型类型 (@987654329 @.
  • @Palle 不知道你在哪里试过,因为在操场上(Swift 3.1)它不能编译
  • 我试图修复您的错误,但对我来说一切都很好。我只注意到通过注释 init 或在子类中覆盖它,它开始编译。看起来编译器无法找出 D.T 类型
  • 这看起来像一个错误——代码不能在 Swift 3.0.2 中编译,但在 Swift 3.1 中可以。
  • @LucaD'Alberti 我在 REPL 中进行了尝试,并使用了我使用 swiftc 编译的文件

标签: swift generics swift3


【解决方案1】:

我首先说我无法弄清楚您的问题发生的原因,但我希望这能以某种方式帮助您

让我们从C1 类开始。

class C1<D: P> {}

通过使用它,一切正常。所以我想确保泛型参数可以在C1C2 中使用,实际上它可以

class C1<D: P> {
    // it compiles
    let something: D.T? = nil

    // it compiles
    func doSomething(using parameter: D.T) {
    }

    // do not compile
    init(_ some: D.T) {
    }
}

最后,如果你覆盖C2类中的init,代码最终编译通过。 我认为这实际上可能是编译器问题,我会尝试为此提交雷达。我真的不知道还能尝试什么。

【讨论】:

  • 谢谢@Luca!覆盖init 确实解决了这个问题,尽管我同意编译器中一定存在一些错误。我的特定用例有点复杂,为参数创建一个具有不同名称的新 init 解决了这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 2015-09-15
相关资源
最近更新 更多