Swift中的Java-esque枚举

时间:2016-04-11 00:53:11

标签: java swift enums

我已经使用Java一段时间了,目前正在学习Swift。在Java中,我在创建小游戏时使用枚举作为一种学习语言的方式。然而,在这场比赛中开始构建“比赛”和“武器”时,我遇到了一个问题。 Swift不像Java那样处理枚举。所以我的问题是如何在Swift中编写以下Java代码,以便以类似的方式使用它。

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

2 个答案:

答案 0 :(得分:4)

最明显的方式是:

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

并且,重新定义operator ==,您可以获得相等比较:

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)

很多选项,主要取决于你真正想要做什么以及你需要在枚举中包含多少数据。

答案 1 :(得分:2)

这是完成任务的一种快速而肮脏的方法:

typealias WeaponName = String
typealias WeaponDamage = Int

enum Weapon {
    case Sharp( WeaponName, WeaponDamage )
    case Blunt( WeaponName )
    case Broken

    var name: WeaponName {
        switch self {
        case let .Sharp( name, _):
            return name
        case let .Blunt( name ):
            return name
        case .Broken:
            return "Broken"
        }
    }

    var damage: WeaponDamage {
        switch self {
        case let .Sharp( _, damage ):
            return damage
        case .Broken:
            return 0
        default:
            return 5
        }
    }

}


var woodenSword = Weapon.Sharp( "Wooden Sword", 5 )
var ironSword = Weapon.Sharp( "Iron Sword", 10 )
var club = Weapon.Blunt( "Mr. Sticky" )

print( woodenSword.name )    // "Wooden Sword"
print( woodenSword.damage )  // 10
print( club.name )           // "Mr. Sticky"