有没有办法将像字典元组这样的非文字值映射到枚举?以下代码将抛出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": ""]
}
Run Code Online (Sandbox Code Playgroud)
当我使用元组时它是一样的:
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: "")
}
Run Code Online (Sandbox Code Playgroud)
@Antonio 提供了解决方法,但没有回答实际问题。
定义你的枚举。
enum FileType {
case Image, Video
}
Run Code Online (Sandbox Code Playgroud)
为 case 提供非文字值,无论您想要符合RawRepresentable协议的类型。通过枚举扩展来获得更清晰的代码。
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/")
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了能够Tuple在 switch 中匹配,实现模式匹配运算符。
private func ~= (lhs: FileType.Tuple, rhs: FileType.Tuple) -> Bool {
return lhs.contentTypeMatcher == rhs.contentTypeMatcher && lhs.name == rhs.name
}
Run Code Online (Sandbox Code Playgroud)
就是这样...
let a = FileType.Image
print(a.rawValue.name) // "Image"
let b = FileType(rawValue: a.rawValue)!
print(a == b) // "true"
print(b.rawValue.contentTypeMatcher) // "image/"
Run Code Online (Sandbox Code Playgroud)
假设我没有质疑地回答了这个问题。现在......枚举(至少在 Swift 中)被设计为具有独特的案例。对此解决方法的警告是,您可以(我希望是偶然的)rawValue在更多情况下保持相同。一般来说,你的示例代码对我来说很奇怪。除非您(出于非常合理的原因)需要从元组创建新的枚举值,否则请考虑重新设计。如果您想采用这种解决方法,我建议(取决于项目)对所有 case 原始值是否唯一进行一些检查。如果没有,请考虑:
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/"
}
}
Run Code Online (Sandbox Code Playgroud)
语言参考在谈论枚举声明时明确指出:
原始值类型必须符合 Equatable 协议和以下文字可转换协议之一:IntegerLiteralConvertible(适用于整数文字)、FloatingPointLiteralConvertible(适用于浮点文字)、StringLiteralConvertible(适用于包含任意数量字符的字符串文字)以及 ExtendedGraphemeClusterLiteralConvertible(适用于包含任意数量字符的字符串文字)仅包含单个字符。
因此,除了文字之外,没有其他东西可以用作原始值。
一种可能的解决方法是将字典表示为字符串 - 例如,您可以使用逗号分隔元素,并使用冒号分隔键和值:
enum FileType : String {
case VIDEO = "name:Video,contentTypeMatcher:video/"
case IMAGE = "name:Image,contentTypeMatcher:image/"
...
}
Run Code Online (Sandbox Code Playgroud)
然后,使用计算属性(或方法,如果您愿意)重建字典:
var dictValue: [String : String] {
var dict = [String : String]()
var elements = self.rawValue.componentsSeparatedByString(",")
for element in elements {
var parts = element.componentsSeparatedByString(":")
if parts.count == 2 {
dict[parts[0]] = parts[1]
}
}
return dict
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5162 次 |
| 最近记录: |