Swift - 为什么即使where子句专门设置了相关类型,协议仍被视为通用协议?

问题描述 投票:2回答:1

我有一个通用的协议:

protocol GenericProtocol {
  associatedtype GenericParameter
}

我无法像这样使用它:

var someValue: GenericProtocol?

我收到了大家都知道的错误信息:

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

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

protocol ConcreteProtocol: GenericProtocol where GenericParameter == Bool { }

但即便如此,我也无法在类型签名中使用:

var someValue: ConcreteProtocol?

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

我误解了where条款的含义吗?甚至约束子协议必须被视为通用的概念性原因是什么?我确信这不是一个bug,而是一个Swift社区已知的语言的有目的的事实。任何人都可以向我解释这个吗?

此外,如果有人能提供一种方法,我可以实现我想要的东西,将非常感激,虽然我不确定它是否可能。

swift generics inheritance protocols where-clause
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.