Swift中的高级Java枚举

时间:2015-07-01 09:08:20

标签: java ios swift enums

我需要转换为Swift代码的许多Java类。 其中一个类有一个高级枚举:

public enum Student {

  STUDENT_ONE("Steve", "Jobs")
  STUDENT_TWO("Tim", "Cook")

  private String _firstName;
  private String _lastName;
}

如何在Swift中复制相同的行为?

5 个答案:

答案 0 :(得分:3)

经过一番思考后,我同意godmoney的观点,即使用字符串,我的解决方案更好。

无论如何,这里是aksh1t解决方案的一个更简洁的变体,只使用一个返回元组的计算属性:(在Swift 2.0中测试)

enum Student {
    case STUDENT_ONE, STUDENT_TWO

    typealias Details = (firstName: String, lastName: String)
    var details : Details {
        switch(self) {
        case STUDENT_ONE : return ("Steve", "Jobs")
        case STUDENT_TWO : return ("Tim", "Cook")
        }
    }
}

// Usage:
func test(sd: Student.Details) {
    print(sd.firstName)
    print(sd.lastName)
}
test(Student.STUDENT_ONE.details)

答案 1 :(得分:2)

我试图将Java代码转换为Swift做同样的事情,最后做了类似的事情:

public enum Student {

    case STUDENT_ONE
    case STUDENT_TWO

    var firstName: String {
        get {
            switch self {
            case .STUDENT_ONE:
                return "Steve"
            case .STUDENT_TWO:
                return "Tim"
            }
        }
    }

    var lastName: String {
        get {
            switch self {
            case .STUDENT_ONE:
                return "Jobs"
            case .STUDENT_TWO:
                return "Cook"
            }
        }
    }
}

现在,这真是漫长而凌乱,我不确定这是否是正确的做法,但我无法找到其他有效的方法。我很想知道是否还有其他更好的方法。

答案 2 :(得分:1)

这就是我最终要做的事情 - 根本不确定这一点:

struct Students {

    enum Students {
        case STUDENT_ONE(String, String)
        case STUDENT_TWO(String, String)
    }

    let STUDENT_ONE = Students.STUDENT_ONE("Steve", "Jobs")
    let STUDENT_TWO = Students.STUDENT_TWO("Steve", "Two")
}

答案 3 :(得分:1)

枚举不一定是表示此类数据的最佳选择。我选择了struct s,这很有效,使用正确的访问器:

public struct Student {
    public let firstName : String
    public let lastName : String

    public static let STUDENT_ONE = Student(firstName: "Steve", lastName: "Jobs")
    public static let STUDENT_TWO = Student(firstName: "Tim", lastName: "Cook")
}

答案 4 :(得分:0)

从另一个标记为重复的问题移至此处,因此变量名称不完全匹配,但是概念完全相同。

最明显的方法是:

public enum EnumWeapon {
    case WOODEN_SWORD
    case STONE_SWORD
    case STEEL_SWORD

    func getName() -> String {
        switch self {
        case WOODEN_SWORD:  return "Wooden Sword"
        case STONE_SWORD:   return "Stone Sword"
        case STEEL_SWORD:   return "Steel Sword"
        }
    }

    func getDamage() -> Int {
        switch self {
        case WOODEN_SWORD:  return 4
        case STONE_SWORD:   return 6
        case STEEL_SWORD:   return 8
        }
    }
}

如果您有一个与每个枚举大小写关联的值,则可以使用原始值语法,也可以仅使用它来简化上面的枚举大小写:

public enum Weapon : Int {
    case WOODEN_SWORD = 4
    case STONE_SWORD = 6
    case STEEL_SWORD = 8

    func getDamage() -> Int {
        return rawValue
    }

    func getName() -> String {
        switch self {
        case .WOODEN_SWORD: return "Wooden Sword"
        case .STONE_SWORD:  return "Stone Sword"
        case .STEEL_SWORD:  return "Steel Sword"
        }
    }
}

很明显,如果不需要名称,则可以省略getName函数。同样,您可以省略getDamage函数,而只需使用weapon.rawValue

一种更简单的方法,但与实际的Java实现更相似,将使用结构而不是枚举,例如:

public struct Weapon {
    public let name : String
    public let damage : Int

    private init(name:String, damage:Int) {
        self.name = name
        self.damage = damage
    }

    public static let WOODEN_SWORD = Weapon(name: "Wooden Sword", damage: 4)
    public static let STONE_SWORD = Weapon(name: "Stone Sword", damage: 6)
    public static let STEEL_SWORD = Weapon(name: "Steel Sword", damage: 8)
}

,然后重新定义运算符==,就可以得到相等比较:

func == (lhs:Weapon, rhs:Weapon) -> Bool {
    return lhs.name == rhs.name && lhs.damage == rhs.damage
}

,然后通过重新定义运算符〜=,您可以按预期工作:

func ~= (lhs:Weapon, rhs:Weapon) -> Bool {
    return lhs == rhs
}

func test(sword:Weapon) {
    switch sword {
    case Weapon.STONE_SWORD:    print("stone")
    default:                    print("something else")
    }
}

test(Weapon.STONE_SWORD)

大量选项,主要取决于您真正要执行的操作以及枚举中需要包装的数据量。