swift - Swift 中非文字值的枚举

标签 swift enums

有什么方法可以将非文字值(如字典的元组)映射到枚举?以下代码将抛出 Raw value for enum must be literal

enum FileType {
    case VIDEO = ["name": "Video", "contentTypeMatcher": "video/"]
    case IMAGE = ["name": "Image", "contentTypeMatcher": "image/"]
    case AUDIO = ["name": "Audio", "contentTypeMatcher": "aduio/"]
    case PDF   = ["name": "PDF", "contentTypeMatcher":"application/pdf"]
    case TEXT  = ["name": "Text", "contentTypeMatcher": "text/"]
    case FOLDER= ["name": "Folder", "contentTypeMatcher" :"application/x-directory"]
    case PLAIN = ["name": "Plain", "contentTypeMatcher": ""]
}

当我使用元组时也是一样的:

enum FileType {
    case VIDEO  = (name: "Video", contentTypeMatcher: "video/")
    case IMAGE  = (name: "Image", contentTypeMatcher: "image/")
    case AUDIO  = (name: "Audio", contentTypeMatcher: "aduio/")
    case PDF    = (name: "PDF", contentTypeMatcher:"application/pdf")
    case TEXT   = (name: "Text", contentTypeMatcher: "text/")
    case FOLDER = (name: "Folder", contentTypeMatcher :"application/x-directory")
    case PLAIN  = (name: "Plain", contentTypeMatcher: "")
}

最佳答案

@Antonio 给出了解决方法,但没有回答实际问题。

定义你的枚举。

enum FileType {

    case Image, Video
}

为案例提供非文字值,无论您想要什么类型,都符合 RawRepresentable 协议(protocol)。通过枚举扩展来实现更简洁的代码。

extension FileType: RawRepresentable {

    typealias Tuple = (name: String, contentTypeMatcher: String)

    private static let allCases = [FileType.Image, .Video]

    // MARK: RawRepresentable

    typealias RawValue = Tuple

    init?(rawValue: Tuple) {

        guard let c = { () -> FileType? in

            for iCase in FileType.allCases {
                if rawValue == iCase.rawValue {
                    return iCase
                }
            }
            return nil

        }() else { return nil }
        self = c
    }

    var rawValue: Tuple {

        switch self {
        case .Image: return Tuple("Image", "image/")
        case .Video: return Tuple("Video", "video/")
        }
    }
}

为了能够在 switch 中匹配 Tuple,实现模式匹配运算符。

private func ~= (lhs: FileType.Tuple, rhs: FileType.Tuple) -> Bool {

    return lhs.contentTypeMatcher == rhs.contentTypeMatcher && lhs.name == rhs.name
}

就是这样......

let a = FileType.Image
print(a.rawValue.name) // "Image"
let b = FileType(rawValue: a.rawValue)!
print(a == b) // "true"
print(b.rawValue.contentTypeMatcher) // "image/"

假设我没有提问就回答了问题。现在......枚举(至少在 Swift 中)被设计成具有独特的案例。需要注意的是,您可以(我希望是偶然的)在更多情况下保持相同的 rawValue 。一般来说,你的示例代码让我闻起来。除非您(出于非常合理的原因)需要从元组创建新的枚举值,否则请考虑重新设计。如果您想使用此解决方法,我建议(取决于项目)实现一些检查是否所有案例原始值都是唯一的。如果没有,考虑一下:

enum FileType {

    case Video, Image

    var name: String {
        switch self {
        case .Image: return "Image"
        case .Video: return "Video"
    }

    var contentTypeMatcher: String {
        switch self {
        case .Image: return "image/"
        case .Video: return "video/"
    }
}

关于swift - Swift 中非文字值的枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27347396/

相关文章:

java - 是否可以为特定枚举设置构造函数?

java - 使用泛型传递枚举列表

c# - 使用枚举数据 C# 创建对象列表

ios - Swift - 自定义 SectionIndexTitles 在 Tableview 中不起作用

iOS( swift ): Presenting View Controller Embedded in Navigation Controller

swift - UIViewController 子类似乎加载了不需要的 Nib

swift - ios9 的 ScrollView 和导航栏

ruby-on-rails - rails_admin gem 破坏了 Rails 4.1 中引入的枚举属性

c++ - Switch 语句不适用于枚举 (C++)

ios - 以编程方式带有边距的 UITextField 自动布局