我正在尝试创建一个简单的协议,用于确定对象是处于“开”状态还是“关”状态。对于实现对象,其解释取决于该对象。对于UISwitch
,它表示开关是否打开或关闭(显然)。对于UIButton
,它可以表示按钮是否处于selected
状态。对于Car
,它可以表示汽车引擎是否开启,甚至可以表示汽车是否在移动。因此,我开始创建这个简单的协议:
protocol OnOffRepresentable {
func isInOnState() -> Bool
func isInOffState() -> Bool
}
现在我可以像这样扩展上述的用户界面控件:
extension UISwitch: OnOffRepresentable {
func isInOnState() -> Bool { return on }
func isInOffState() -> Bool { return !on }
}
extension UIButton: OnOffRepresentable {
func isInOnState() -> Bool { return selected }
func isInOffState() -> Bool { return !selected }
}
现在我可以创建一个这些对象的数组,并循环检查它们是否打开或关闭:
let booleanControls: [OnOffRepresentable] = [UISwitch(), UIButton()]
booleanControls.forEach { print($0.isInOnState()) }
太好了!现在我想要创建一个字典,将这些控件与一个UILabel
相映射,以便当控件状态改变时,我可以更改与控件关联的标签文本。所以我开始声明我的字典:
var toggleToLabelMapper: [OnOffRepresentable : UILabel] = [:]
// error: type 'OnOffRepresentable' does not conform to protocol 'Hashable'
哦!对了!我真是个傻瓜。好的,让我使用协议合成来更新协议(毕竟,我想在这里使用的控件都是可哈希的:UISwitch、UIButton等):
protocol OnOffRepresentable: Hashable {
func isInOnState() -> Bool
func isInOffState() -> Bool
}
但现在我遇到了一系列新的错误:
error: protocol 'OnOffRepresentable' can only be used as a generic constraint because it has Self or associated type requirements
error: using 'OnOffRepresentable' as a concrete type conforming to protocol 'Hashable' is not supported
好的...所以我进行了一些堆栈溢出的挖掘和搜索。我发现了许多看起来很有前途的文章,比如Swift中的Set和协议,使用某些协议作为符合另一个协议的具体类型不受支持,而且我看到有一些很棒的类型擦除文章,似乎正是我需要的:http://krakendev.io/blog/generic-protocols-and-their-shortcomings,http://robnapier.net/erasure,以及https://realm.io/news/type-erased-wrappers-in-swift/ 只是其中几个。
但这就是我卡住的地方。我尝试阅读所有这些文章,也尝试着创建一个类,使其同时符合Hashable
和我的OnOffRepresentable
协议,但我无法弄清如何将它们联系起来。
Hashable
部分插入其中。Rob Napier的博客也是一样...也许。他的'Animal'协议是在一个'Food'关联类型上通用的,但这也不是我正在做的。realm.io的示例似乎是最好的选择,但'SequenceType'也与我的特定需求非常不同。 - Tim Fuqua