Swift-为什么即使where子句专门化了关联的类型,协议仍然被视为泛型?

Swift-为什么即使where子句专门化了关联的类型,协议仍然被视为泛型?,swift,generics,inheritance,protocols,where-clause,Swift,Generics,Inheritance,Protocols,Where Clause,我有一个通用协议: protocol GenericProtocol { associatedtype GenericParameter } protocol ConcreteProtocol: GenericProtocol where GenericParameter == Bool { } 我不能像这样使用它: var someValue: GenericProtocol? 我得到了我们都很清楚的错误信息: 协议“GenericProtocol”只能用作泛型约束,因为它具有自身或

我有一个通用协议:

protocol GenericProtocol {
  associatedtype GenericParameter
}
protocol ConcreteProtocol: GenericProtocol where GenericParameter == Bool { }
我不能像这样使用它:

var someValue: GenericProtocol?
我得到了我们都很清楚的错误信息:

协议“GenericProtocol”只能用作泛型约束,因为它具有自身或关联的类型要求

我多次遇到这个错误,花了很长时间思考这个错误的概念原因,我想我至少在某种程度上理解了它。我不明白的是,为什么我不能创建一个从我的通用协议继承并专门化的协议,这样它就可以在类型签名中使用。以下是继承协议:

protocol GenericProtocol {
  associatedtype GenericParameter
}
protocol ConcreteProtocol: GenericProtocol where GenericParameter == Bool { }
但即使这样,我也不能在类型签名中使用:

var someValue: ConcreteProtocol?
协议“ConcreteProtocol”只能用作泛型约束,因为它具有自身或关联的类型要求

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

此外,如果有人能提供一种方式,让我能够实现我想要的,我将不胜感激,尽管我不确定这是否可能

var someValue: GenericProtocol?
如果你想试试的话,这不起作用的原因是显而易见的

var someValue: Class = Class1()
someValue            = Class2()
关键是你有一个协议,它对于你在那里分配的每一种类型都是不同的,例如有不同的方法类型,这使得
someValue
不可用

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

可能不起作用,因为类可能要覆盖
associatedtype
,因此无法分配给
someValue
。所以在语言中实现这一点可能会拒绝重写类,因为
ConcreteProtcol
已经可以在它的一个扩展中使用
GenericParameter==Bool

如果我理解正确的话,这里有一本关于它们的书,你是说我所写的为关联的类型提供了一个默认值,但是,由于默认关联类型可以被一致性类型覆盖,编译器仍然不能假定它知道
genericparmeter==Bool
。这是有道理的,,但我觉得只有在扩展中使用typealias来提供此默认值时,它才应该适用-我认为,由于我在协议的定义中使用where子句指定了关联的类型,因此它不受一致性类型的更改,这将更有意义。另一种猜测是
someValue
应该仍然可用作
GenericProtocol
,因为它也实现了这一点,但它不能,因为
只能用作通用约束。泛型约束可能是实现协议的类,也可能是受约束实现协议的泛型(class?!)参数。