【问题标题】:How can Swift protocol conform to type parameter protocolSwift 协议如何符合类型参数协议
【发布时间】:2015-11-05 22:07:00
【问题描述】:

我遵循了相当直接的 Swift 2.0 代码

protocol PA {
    init(handle:Int)
}

class CB: PA {
    required init(handle:Int) {}
}

class X {
    func test<U:PA>() -> U {
        return U(handle: 1)
    }
}

class ThisFails {
    func foo() -> PA {
        return X().test()
    }
}

但编译失败并显示相当奇怪的错误消息

swift:23:20:错误:无法推断通用参数“U” 返回 X().test()

我希望 U 被推断为 PA 类型

将方法 foo 的返回类型更改为 CB 使其工作,但我有很多实现 PA 协议的类,所以这对我不起作用。

类似地从 U:PA 中删除 PA 约束,编译器将其推断为 foo 内的 PA 类型,但我需要在 test 内进行 constrained 调用,这样也无济于事。

【问题讨论】:

  • 这是“正常的”。 test()->U 是函数,参数为 U 类型,返回 U 类型的实例。 foo 返回类型为 PA.Type,而不是符合 PA 的类型,如 U:PA。换句话说,从protocol.Type 创建一个实例是不可能的。尝试让 a = Any()。它也不可用。

标签: swift generics


【解决方案1】:

嗯...这个问题在错误信息中已经说得很清楚了! 关键是您使用泛型声明了一个函数,并且泛型类型对协议有约束。然后使用泛型 U 编写方法 test()... 这意味着当您实际使用该方法时,编译器必须清楚符合协议 PA 的实际类型是什么,由 test() 实例化和返回. 在函数 foo 中,这并不清楚......你怎么能期望 test 在它从未被提及时返回 CB?试试:

X().test<CB>()

【讨论】:

  • 错误 ... return X().test() 不应该工作。你不能明确地专门化一个泛型函数
  • 你不能在 Swift 中明确地特化一个泛型函数
【解决方案2】:
class ThisFails {
    func foo() -> PA {
        return X().test()   // error: generic parameter 'U' could not be inferred
    }
}

X().test() as PA            // error: generic parameter 'U' could not be inferred

检查下一行

X().test()       // error: generic parameter 'U' could not be inferred
X().test() as CB // no error

问题是如何创建一个未知类型的实例。编译器所知道的是类型应该符合协议。这还不够,是吗?

tryclass ThisFails {
    func foo<U:PA>() -> U {
        return X().test()
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 2016-11-17
    • 1970-01-01
    相关资源
    最近更新 更多