【问题标题】:Swift cannot convert value of type which matches generic constraintsSwift 无法转换与泛型约束匹配的类型值
【发布时间】:2018-09-27 14:56:25
【问题描述】:

给定以下类型

protocol AProtocol {}
protocol AnotherProtocol {}
class AClass: AProtocol, AnotherProtocol {}

我有点困惑为什么会抛出以下错误:“错误:无法将'AClass'类型的值转换为指定的'T'类型”

class generic<T> where T:AProtocol, T:AnotherProtocol {
    let prop: T = AClass()
}

但以下工作正常:

class generic<T> where T: AProtocol, T: AnotherProtocol {
    let prop: T
    init(withProp prop: T) { self.prop = prop }
}

let instance = generic<AClass>(withProp: AClass())

【问题讨论】:

  • 因为如果你有一些BClass 也实现了AProtocol &amp; AnotherProtocol,那么T 可能是BClass,而不是AClass。除非您在约束中指定特定类,否则您不能为 T 假定特定类
  • 换句话说,不可能从泛型类的实现内部引用泛型类型的实现?

标签: swift generics types swift4


【解决方案1】:

类的通用参数由类的用户指定,而不是

您不能说T 必须是AClass,就像您在第一个未编译的代码sn-p 中所做的那样,因为T 是由用户指定的。您班级的用户可能需要以下内容:

let myObject = generic<BClass>()

其中BClass 满足约束条件。那么当用户试图访问该属性时会发生什么?他会得到一个AClass 的实例,但T 实际上是BClass,所以他真的应该得到一个BClass。看到这里的矛盾了吗?

关于您的评论:

换句话说,不可能从泛型类的实现内部引用泛型类型的实现?

没错,因为你不知道这些类型会是什么。您可以调用在AProtocolAnotherProtocol 中声明的方法。通用约束确保这些方法存在。

如果你想让它按照你想要的方式工作,你需要所谓的协议组合

var someProperty: (AProtocol & AnotherProtocol) = AClass()

【讨论】:

  • 啊!灯泡时刻,是的,矛盾一清二楚。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多