我想以通用方式将多个值与枚举值相关联.
这可以用Java完成:
enum Test { A("test",2); final String var1; final int var2; Test (String var1,int var2) { this.var1 = var1; this.var2 = var2; } } public static void main(String []args){ Test test = Test.A; System.out.println(test.var1); }
但看起来Swift是不可能的?到目前为止,根据docs,有:
>相关价值观.示例(从docs开始):
enum Barcode { case UPCA(Int,Int,Int) case QRCode(String) }
但这不是我需要的.
>原始价值.示例(从docs开始):
enum ASCIIControlCharacter: Character { case Tab = "\t" case LineFeed = "\n" case CarriageReturn = "\r" }
这将是我需要的,但它只能有一个值!
这个有优雅的解决方案……?似乎是一种语言设计决策,因为它会与相关的价值概念发生冲突,至少在目前的形式中如此.我知道我可以使用例如一个字典,用于将枚举值映射到其余部分,但实际上缺少在一个安全的步骤中执行此操作,如在Java中.
对于Swift枚举,您只能使用(String | Integer | Float)LiteralConvertible类型作为原始值.如果要使用现有类型(例如CGPoint)作为原始值,则应遵循@Alex答案.
我将在这个答案中提供2个备选方案
很简单的解决方案
enum Test: String { case A = "foo:1" case B = "bar:2" var var1: String { return split(self.rawValue,{ $0 == ":" })[0] } var var2: Int { return split(self.rawValue,{ $0 == ":" })[1].toInt()! } } let test = Test.A println(test.var1) // -> "foo"
你不喜欢这个吗?去下一个:)
使用struct和static常量的行为模拟
struct Test { let var1: String let var2: Int private init(_ var1:String,_ var2:Int) { self.var1 = var1 self.var2 = var2 } } extension Test { static let A = Test("foo",1) static let B = Test("bar",2) static let allValues = [A,B] } let test = Test.A println(test.var1) // -> "foo"
但是当然,struct缺少enum的一些功能.你必须手动实现它.
Swift enum隐式符合Hashable协议.
extension Test: Hashable { var hashValue:Int { return find(Test.allValues,self)! } } func ==(lhs:Test,rhs:Test) -> Bool { return lhs.var1 == rhs.var1 && lhs.var2 == rhs.var2 } Test.A.hashValue // -> 0 Test.B.hashValue // -> 1 Test.A == Test.B // -> false
在第一个代码中,我们已经拥有与Java中的values()对应的allValues. Java中的valueOf(…)等同于Swift中RawRepresentable协议中的init?(rawValue :):
extension Test: RawRepresentable { typealias RawValue = (String,Int) init?(rawValue: RawValue) { self.init(rawValue) if find(Test.allValues,self) == nil{ return nil } } var rawValue: RawValue { return (var1,var2) } } Test(rawValue: ("bar",2)) == Test.B Test(rawValue: ("bar",4)) == nil
等等…
我知道这不是“通用的”.我们永远无法模仿的一件事是Swift中的“Matching Enumeration Values with a Switch Statement”功能.你总是需要默认情况:
var test = Test.A switch test { case Test.A: println("is A") case Test.B: println("is B") default: fatalError("cannot be here!") }