Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java-esque enum in Swift [duplicate]

Tags:

java

enums

swift

I have used Java for a while now and am currently learning Swift. In Java I use enumeration quite a bit when creating little games as a way of learning the language. However upon beginning to construct "races" and "weapons" in this game I came across an issue. Swift doesn't handle enum the same way Java does. So my question is how do I write the following Java code in Swift so it can be used in a similar way.

public enum EnumWeapon {
    WOODEN_SWORD("Wooden Sword", 4),
    STONE_SWORD("Stone Sword", 6), 
    STEEL_SWORD("Steel Sword", 8); 

    private String name;
    private int damage;

    private EnumWeapon(String name, int damage) {
        this.name = name;
        this.damage = damage;
    }

    public String getName() {
        return name;
    }

    public int getDamage() {
        return damage;
    }
}
like image 398
Austin E Avatar asked Feb 07 '26 03:02

Austin E


1 Answers

The most obvious way would be:

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
        }
    }
}

If you have a single value to associate with each enum case, you can use the raw value syntax, or just use it to simplify the enum case above:

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"
        }
    }
}

Obviously, if you don't need the name, you can omit the getName function. Likewise you can omit the getDamage function and just use weapon.rawValue

An even simpler way, and yet more analogous to the actual Java implementation, would be to use a struct instead of an enum, as:

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)
}

and, be redefining operator ==, you can get equality comparisons:

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

and, by redefining operator ~= you can get switch to work as expected:

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)

A whole lot of options, mostly it just depends on what you're really trying to do and how much data you need to wrap in the enum.

like image 86
David Berry Avatar answered Feb 09 '26 17:02

David Berry



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!