Swift-为什么即使where子句已将相关类型专门化,协议仍被视为泛型?

时间:2018-09-06 09:15:13

标签: swift generics inheritance protocols where-clause

我有一个通用协议:

protocol GenericProtocol {
  associatedtype GenericParameter
}

我无法像这样使用它:

var someValue: GenericProtocol?

我收到我们都知道的错误消息:

  

协议'GenericProtocol'只能用作通用约束,因为它具有Self或关联的类型要求

已经多次遇到此错误,并且花了很长时间思考此错误的概念性原因,我认为我至少已经有所了解。我不明白的原因是为什么我不能创建一个从我的通用协议继承并专门化的协议,以便可以在类型签名中使用它。这是继承协议:

protocol ConcreteProtocol: GenericProtocol where GenericParameter == Bool { }

但是即使如此,我也不能在类型签名中使用

var someValue: ConcreteProtocol?
  

协议'ConcreteProtocol'只能用作通用约束,因为它具有Self或关联的类型要求

我误解了where子句的含义吗?即使是受约束的子协议也必须被视为通用的概念上的原因是什么?我确信这不是错误,而是Swift社区已知的一种有目的的事实。谁能向我解释一下?

即使有人不确定我能否实现我想要的目标,也将不胜感激。

1 个答案:

答案 0 :(得分:1)

var someValue: GenericProtocol?

如果您想尝试一下,为什么这样行不通

var someValue: Class = Class1()
someValue            = Class2()

重点是您拥有一个协议,该协议针对您分配给它的每种类型都不同,例如具有不同的方法类型,这使得someValue无法使用。

protocol ConcreteProtocol: GenericProtocol where GenericParameter == Bool { }
var someValue: ConcreteProtocol?

可能不起作用,因为类可能要覆盖associatedtype,因此无法分配给someValue。因此,用该语言实现此功能可能会拒绝覆盖类,因为ConcreteProtcol可以在其扩展名之一中使用GenericParameter == Bool