Swift非常长的枚举与一个不同的情况:如何处理?
我尝试用HTML颜色制作enum。第一刻,我以为它会很好,很简单,但我撞到了墙。颜色可以定义为名称:Swift非常长的枚举与一个不同的情况:如何处理?,swift,Swift,我尝试用HTML颜色制作enum。第一刻,我以为它会很好,很简单,但我撞到了墙。颜色可以定义为名称:moroon、gray、gray(相同值)或RGBA字符串#00000000。我的起点是: enum HTMLColor { case aliceblue case antiquewhite case aqua case aquamarine case azure //..... many, many names and at the end:
moroon
、gray
、gray
(相同值)或RGBA字符串#00000000
。我的起点是:
enum HTMLColor {
case aliceblue
case antiquewhite
case aqua
case aquamarine
case azure
//..... many, many names and at the end:
case custom(String)
}
嗯。由于lastcustom
和一些双重名称(灰色、灰色),我无法定义原始类型。因此,我添加了两个长开关name和hextstring:
public var name:String {
switch self {
case .aliceblue: return "aliceblue"
case .antiquewhite: return "antiquewhite"
case .aqua: return "aqua"
case .aquamarine: return "aquamarine"
case .azure: return "azure"
//..... many, many names and at the end:
case .custom(let string): return string
}
}
与hexString类似–但是我可以返回“#00000000”
来代替名称
但是现在我不知道如何实现init(来自string:string)
或init(来自decoder:decoder)
。我想要
let azure = HTMLColor(from: "azure")
并且得到了.azure
或:
并获得.hexString(hexValue)
以将其用作:
switch color {
case .custom(let string): makeRealColorFromString(string)
default: makeRealColorFromString(color.hexString)
}
对于这个特定的问题,
enum
可能不是一个好主意?您可以使用struct
来解决这个问题。像这样:
struct HTMLColor: RawRepresentable, Codable {
typealias RawValue = String
var rawValue: String
}
然后,您可以在任意位置添加颜色盒,也可以在任意位置添加颜色盒:
extension HTMLColor {
static let aliceblue = HTMLColor(rawValue: "aliceblue")
static let antiquewhite = HTMLColor(rawValue: "antiquewhite")
static let aqua = HTMLColor(rawValue: "aqua")
static let aquamarine = HTMLColor(rawValue: "aquamarine")
static let azure = HTMLColor(rawValue: "azure")
//..... many, many names, and even:
static let customBlack = HTMLColor(rawValue: "#00000000")
}
现在,您可以在代码中的任何位置使用HTMLColor.azure
或执行let custom=HTMLColor(rawValue:“#AB0023FF”)
对于
RawRepresentable
而言,默认编码/解码将采用/fromRawValue
类型(这里是String
)。您可以使用struct
。像这样:
struct HTMLColor: RawRepresentable, Codable {
typealias RawValue = String
var rawValue: String
}
然后,您可以在任意位置添加颜色盒,也可以在任意位置添加颜色盒:
extension HTMLColor {
static let aliceblue = HTMLColor(rawValue: "aliceblue")
static let antiquewhite = HTMLColor(rawValue: "antiquewhite")
static let aqua = HTMLColor(rawValue: "aqua")
static let aquamarine = HTMLColor(rawValue: "aquamarine")
static let azure = HTMLColor(rawValue: "azure")
//..... many, many names, and even:
static let customBlack = HTMLColor(rawValue: "#00000000")
}
现在,您可以在代码中的任何位置使用HTMLColor.azure
或执行let custom=HTMLColor(rawValue:“#AB0023FF”)
对于
RawRepresentable
而言,默认的编码/解码将采用/fromRawValue
类型(这里是String
)。正如其他人所指出的,enum
(尽管直觉如此)可能不是实现此功能的最佳选择。话虽如此,如果您确实想使用枚举,您可以这样做:
enum HTMLColor: CaseIterable, ExpressibleByStringLiteral {
case white
case black
// ... others
case custom(String)
static var allCases: [HTMLColor] {
return [.white, .black] // All except .custom here
}
var name: String {
switch self {
case .white: return "white"
case .black: return "black"
// ... others
case .custom(let string): return string
}
}
var hexString: String {
switch self {
case .white: return "#FFFFFFFF"
case .black: return "#00000000"
// ... others
case .custom(let string): return string
}
}
init(stringLiteral: String) {
self = HTMLColor.allCases.first(where: { ($0.name == stringLiteral) || ($0.hexString == stringLiteral) }) ?? .custom(stringLiteral)
}
}
let c1: HTMLColor = "#FFFFFFFF"
let c2: HTMLColor = "#F2F2F2FF"
let c3: HTMLColor = "black"
print(c1) // --> .white
print(c2) // --> .custom("#F2F2F2FF")
print(c3) // --> .black
本质上,我们遵循ExpressibleByStringLiteral
,这意味着我们可以用字符串文本初始化枚举。然后在初始值设定项中,我们搜索名称和值以查找匹配项或返回一个.custom
无论如何,它都不是一个完整的或生产就绪的解决方案(缺少的一件明显的事情是,它不匹配省略alpha组件或“#”前缀的十六进制值),但您知道了
然后我们可以这样使用它:
enum HTMLColor: CaseIterable, ExpressibleByStringLiteral {
case white
case black
// ... others
case custom(String)
static var allCases: [HTMLColor] {
return [.white, .black] // All except .custom here
}
var name: String {
switch self {
case .white: return "white"
case .black: return "black"
// ... others
case .custom(let string): return string
}
}
var hexString: String {
switch self {
case .white: return "#FFFFFFFF"
case .black: return "#00000000"
// ... others
case .custom(let string): return string
}
}
init(stringLiteral: String) {
self = HTMLColor.allCases.first(where: { ($0.name == stringLiteral) || ($0.hexString == stringLiteral) }) ?? .custom(stringLiteral)
}
}
let c1: HTMLColor = "#FFFFFFFF"
let c2: HTMLColor = "#F2F2F2FF"
let c3: HTMLColor = "black"
print(c1) // --> .white
print(c2) // --> .custom("#F2F2F2FF")
print(c3) // --> .black
最后,您甚至可以扩展对Int-literal初始化的支持(例如,您可以使用
让c:HTMLColor=0xf2ff
),或者使用类似于的工具处理所有代码重复,正如其他人所指出的,enum
(尽管直觉如此)可能不是实现这一点的最佳选择。话虽如此,如果您确实想使用枚举,您可以这样做:
enum HTMLColor: CaseIterable, ExpressibleByStringLiteral {
case white
case black
// ... others
case custom(String)
static var allCases: [HTMLColor] {
return [.white, .black] // All except .custom here
}
var name: String {
switch self {
case .white: return "white"
case .black: return "black"
// ... others
case .custom(let string): return string
}
}
var hexString: String {
switch self {
case .white: return "#FFFFFFFF"
case .black: return "#00000000"
// ... others
case .custom(let string): return string
}
}
init(stringLiteral: String) {
self = HTMLColor.allCases.first(where: { ($0.name == stringLiteral) || ($0.hexString == stringLiteral) }) ?? .custom(stringLiteral)
}
}
let c1: HTMLColor = "#FFFFFFFF"
let c2: HTMLColor = "#F2F2F2FF"
let c3: HTMLColor = "black"
print(c1) // --> .white
print(c2) // --> .custom("#F2F2F2FF")
print(c3) // --> .black
本质上,我们遵循ExpressibleByStringLiteral
,这意味着我们可以用字符串文本初始化枚举。然后在初始值设定项中,我们搜索名称和值以查找匹配项或返回一个.custom
无论如何,它都不是一个完整的或生产就绪的解决方案(缺少的一件明显的事情是,它不匹配省略alpha组件或“#”前缀的十六进制值),但您知道了
然后我们可以这样使用它:
enum HTMLColor: CaseIterable, ExpressibleByStringLiteral {
case white
case black
// ... others
case custom(String)
static var allCases: [HTMLColor] {
return [.white, .black] // All except .custom here
}
var name: String {
switch self {
case .white: return "white"
case .black: return "black"
// ... others
case .custom(let string): return string
}
}
var hexString: String {
switch self {
case .white: return "#FFFFFFFF"
case .black: return "#00000000"
// ... others
case .custom(let string): return string
}
}
init(stringLiteral: String) {
self = HTMLColor.allCases.first(where: { ($0.name == stringLiteral) || ($0.hexString == stringLiteral) }) ?? .custom(stringLiteral)
}
}
let c1: HTMLColor = "#FFFFFFFF"
let c2: HTMLColor = "#F2F2F2FF"
let c3: HTMLColor = "black"
print(c1) // --> .white
print(c2) // --> .custom("#F2F2F2FF")
print(c3) // --> .black
最后,您甚至可以扩展对Int-literal初始化的支持(例如,您可以使用
let c:HTMLColor=0xf2ff
),或者使用类似于的工具处理所有代码重复。虽然您可能可以获得枚举来完成您想要的操作,但我怀疑这不是您的最佳选择。我建议您看看作为Apple UI工具包一部分的UIColor。我不是说你应该使用它(因为我不知道你的应用程序的细节),而是看看它的API。它可能会给您一些关于如何设计枚举或类的想法。有关详细信息,请参阅。虽然您可能可以获得一个枚举来执行所需操作,但我怀疑这不是您的最佳选择。我建议您看看作为Apple UI工具包一部分的UIColor。我不是说你应该使用它(因为我不知道你的应用程序的细节),而是看看它的API。它可能会给您一些关于如何设计枚举或类的想法。请参阅了解详细信息。这与我尝试过的方法完全相同;事实上,enum似乎是一个错误的想法;)非常感谢。这与我尝试过的方法完全相同;事实上,enum似乎是一个错误的想法;)非常感谢。好啊我添加了静态let hexValues:[String:String]=[“aliceblue”:“#F0F8FFFF”,…]以具有十六进制值,动态var hexValues,这并不好,但可以工作。好的。我添加了静态let hexValues:[String:String]=[“aliceblue”:“#F0F8FFFF”,…]以具有十六进制值、动态var hexValues,这虽然不好,但很有效。