Swift:枚举协议(protocol)不起作用

标签 swift enums ios8 protocols

我需要的枚举协议(protocol)定义的一部分是保存一个以“self”为键的字典。所以这是我的第一次尝试:

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 行失败,错误为:

类型“Self”不符合协议(protocol)“Hashable”

为了解决这个问题,我尝试从 Hashable 继承 Orderable,如下所示:

protocol Orderable : Hashable { ...  }

但是,当我尝试这样做时,Playground 崩溃了。

这是解决问题的正确方法吗?

最佳答案

Playground 崩溃的问题不在于您的 Orderable 协议(protocol),而在于您的 Item 枚举。 Orderable 确实需要实现 Hashable 才能正常工作,但是您在 Playground 中看到的问题更多是由于 Item未正确实现 Orderable。当代码编写得不正确时,Playgrounds 仍然相当不稳定,所以我对它崩溃并不感到惊讶。

因此,要解决 Xcode 6.0 中的编译器错误,您需要执行以下操作:

注意:如果您使用的是 Xcode 6.1,请参阅更新。

在您的Orderable 协议(protocol)中,您已将firstlaststrings 定义为只读计算属性,但您已将它们定义为 Item 枚举中的读写存储属性。此外,您还完全忽略了实现 first 属性。

而不是定义last,例如:

static let last : Item = Item.ItemC

它需要被定义为一个var,带有一个返回Item.ItemC的表达式:

static var last : Item { return Item.ItemC }

同样的基本思想可以应用于firststrings

此外,在您的 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 协议(protocol)的属性似乎是 Xcode 6.0 中的一个问题。在 Xcode 6.1 中,按照您原来的方式实现属性是完全合理的。在 Xcode 6.1 Playground 上,这工作正常:

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]! }
}

关于Swift:枚举协议(protocol)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26125863/

相关文章:

c - C 编译器如何处理枚举?

enums - Common Lisp 中的可比较(可排名/可排序)枚举

ios - 在 Apple Swift 中,在什么情况下我不想要隐式解包的可选项?

ios - Facebook result.isCancelled 对于 iOS-8 和 iOS-9 总是正确的,它工作正常

xcode - NSFetchRequest 返回的 AnyObject 数组在 XCTestCase 中的 Swift XCode 6 Beta 4 中转换时出现 "Swift dynamic cast failed"错误

ios - 如何在 didSelectRowAtIndexPath 中触发选定 Nib 单元格的某些转场

ios - 删除特定 pod 中已弃用的 iOS 框架警告

ios - 取消选中后 UIScrollView 不滚动 "Adjust scroll view insets"xcode 6

swift - 从画廊 Swift 捕获图像时,创建具有未知类型的图像格式是错误的

javascript - WebRTC - 如何设置始终使用 TURN 服务器?