【发布时间】:2018-12-19 11:55:56
【问题描述】:
我有以下协议:
protocol PieceViewGateway {
subscript(_ identifier: PieceIdentifier) -> UIView {get}
}
我在很多地方都以这样的方式使用它:
struct SomeKindOfThing {
let viewGateway: PieceViewGateway
}
这一切都很好,非常好。
这是协议的具体实现的一个示例(还有其他实现):
struct ViewDictionaryPieceViewGateway: PieceViewGateway {
let viewDictionary: [PieceIdentifier: UIView]
subscript(identifier: PieceIdentifier) -> UIView {
guard let item = viewDictionary[identifier] else {
fatalError("Gateway has no value for key: \(identifier)")
}
return item
}
}
我有几个这样的协议。另一个是PieceValueGateway,它返回Int,而不是UIView。
我不想为我需要网关的各种不同“方面”实现类似ViewDictionaryPieceViewGateway 的东西。
我试图通过定义一个具有关联类型的协议来模拟网关来实现这一点:
protocol PieceAspectGateway {
associatedtype Aspect
subscript(_ identifier: PieceIdentifier) -> Aspect {get}
}
然后我将PieceViewGateway 与此一致:
protocol PieceViewGateway: PieceAspectGateway {
subscript(_ identifier: PieceIdentifier) -> UIView {get}
}
但是,这会产生很多编译错误:
Protocol 'PieceViewGateway' 只能用作通用约束,因为它具有 Self 或关联的类型要求
在我添加一致性PieceViewGateway: PieceAspectGateway 之前,代码很好报告了错误。例如,SomeKindOfThing 声明它有一个let viewGateway: PieceViewGateway。
我也尝试过这样的一致性:
protocol PieceViewGateway: PieceAspectGateway where Aspect == UIView {
subscript(_ identifier: PuzzlePieceIdentifier) -> UIView {get}
}
像这样:
protocol PieceViewGateway: PieceAspectGateway {
typealias Aspect = UIView
subscript(_ identifier: PuzzlePieceIdentifier) -> UIView {get}
}
…但只要将PieceViewGateway 用作协议,所有这些变体都会产生相同的错误。
有什么方法可以实现吗?
谢谢。
【问题讨论】:
-
你能在问题中添加错误的行吗?但一般现在不能使用
varName: PieceViewGateway,必须声明泛型<T: PieceViewGateway>(varName: T)。
标签: swift swift-protocols