Swift:枚举协议不起作用
我需要一个枚举的协议定义的一部分是将一个以“self”作为关键字的字典。所以这是我第一次尝试:Swift:枚举协议不起作用
protocol Orderable { // line 1
class var first: Self { get }
class var last: Self { get }
class var strings: [Self : String] { get } // line 4
}
enum Item : Int, Orderable {
case ItemA = 0, ItemB, ItemC
static let last : Item = Item.ItemC
var name : String { return Item.strings[self]! }
static let strings: [Item : String] = [
.Item1: "item no. 1", .Item2 : "item no. 2", .Item3: "Item no. 3"
]
}
println ("last item is: \(Item.last.name)") // ==> "last item is: item no. 3"
这未能在第4行出现错误:
型“自我”不符合协议“哈希的”
为了解决这个问题,我试图从Hashable继承Orderable,如下所示:
protocol Orderable : Hashable { ... }
但是,当我尝试该操作时,Playground崩溃。
这是问题的正确解决方案吗?
操作系统崩溃的问题与Orderable
协议没有太大的关系,但更多与您的Item
枚举相关。的确,Orderable
需要执行Hashable
才能正常工作,但是您在Playground中看到的问题更多的是由于Item
未正确执行Orderable
。当代码写得不对时,游乐场还是相当不稳定的,所以对我来说它并没有让你感到惊讶。
因此,要解决该编译器的bug在Xcode 6.0,你需要做到以下几点:
注:如果您使用的Xcode 6.1,看到更新。
在你Orderable
协议,您已经定义first
,last
,并strings
为只读属性计算的,但你将它们定义为读写存储在Item
枚举属性。另外,你忽略了完全实现你的first
属性。
而不是定义last
,例如,作为:
static let last : Item = Item.ItemC
它需要与表达被定义为var
该return
小号Item.ItemC
:
static var last : Item { return Item.ItemC }
相同的基本思想可以是适用于first
和strings
。
而且,在你的strings
财产,你已经使用.Item1
,.Item2
,并.Item3
,而不是.ItemA
,.ItemB
和.ItemC
。
因此,如果我们解决了所有我们得到:
protocol Orderable: Hashable {
class var first: Self { get }
class var last: Self { get }
class var strings: [Self : String] { get }
}
enum Item : Int, Orderable {
case ItemA = 0, ItemB, ItemC
static var first: Item { return .ItemA }
static var last : Item { return .ItemC }
static var strings: [Item: String] {
return [
.ItemA: "item no. 1", .ItemB : "item no. 2", .ItemC: "Item no. 3"
]
}
var name : String { return Item.strings[self]! }
}
,与此快速测试很好地工作:
println("last item is: \(Item.last.name)")
println("first item is: \(Item.first.name)")
println("item B is \(Item.strings[Item.ItemB])")
输出:
last item is: Item no. 3
first item is: item no. 1
item B is Optional("item no. 2")
更新:正如@David在评论中指出的那样,我上面关于在Item
中实现Orderable
协议属性的说法似乎只是Xcode 6.0中的一个问题。在Xcode 6.1中,以最初的方式实现属性是完全合理的。在Xcode 6.1操场,这工作得很好:
protocol Orderable: Hashable {
class var first: Self { get }
class var last: Self { get }
class var strings: [Self : String] { get }
}
enum Item : Int, Orderable {
case ItemA = 0, ItemB, ItemC
static var first: Item = .ItemA
static var last : Item = .ItemC
static var strings: [Item: String] = [
.ItemA: "item no. 1", .ItemB : "item no. 2", .ItemC: "Item no. 3"
]
var name : String { return Item.strings[self]! }
}
protocol ExampleProtocol {
var simpleDescription: String { get }
mutating func adjust()
}
enum SimpleEnum : ExampleProtocol {
case enumMember(String)
var simpleDescription: String {
get {
switch self {
case let .enumMember(descript):
return descript
}
}
}
mutating func adjust() {
switch self {
case let .enumMember(desc):
self = .enumMember(desc + " (adjusted)")
}
}
}
var c = SimpleEnum.enumMember("A simple enum.")
var csimpleDescription = c.simpleDescription
c.adjust()
var dsimpleDescription = c.simpleDescription
某些人发布未注释的代码而没有文字说明或解释 - 这种回答被标记为低质量 – 2015-06-01 18:35:04
他的主要问题是,他不作为扩展可哈希的,您已固定为固定了很多的副作用声明可订购他有其他问题。协议中定义'class var first:Self {get}'只是说协议要求必须有get方法。对实现没有任何限制,实际上可以使用get和set方法来实现它,尽管6.0编译器似乎有问题。在6.1编译器上看起来很好。 – 2014-09-30 20:35:13
@David他们在问题中表示他们试图将'Orderable'声明为'Hashable',并且在我的回答中重申了这一点,所以我认为这已经涵盖了。我的观点主要是因为他们的代码中存在其他问题,所以它没有工作(在他们的案例中,游乐场正在崩溃)。 Re:对属性实现的限制,我没有意识到,谢谢。我当时使用的是6.0编译器,但自从安装了6.1版本的GM之后,我发现你是正确的。我会更新答案以反映这一点。 – 2014-09-30 20:46:21
是的,我只是想指出你正在解决一个编译器错误,它应该没问题。我花了很多东西,包括Hashable,把它分解为变量声明和定义的最小值,它仍然在6.0上崩溃。与语言(和实现)一起工作的荣耀,从生产就绪方面来说还有很长的路要走。 – 2014-09-30 20:52:19