【问题标题】:How to implement an enum with constructor in Swift like Java?如何在像 Java 这样的 Swift 中使用构造函数实现枚举?
【发布时间】:2014-07-17 11:22:41
【问题描述】:

例如,我们有如下 Java 代码;

enum Job {
    NINJA(3000000){
        public void attack() {
            //use Shuriken
        }
    },
    SAMURAI(4000000){
        public void attack() {
            //use Sword
        }
    };
    public final int salary;
    public abstract void attack();
    private Job(int salary) {
        this.salary = salary;
    }
}

在 Swift 中,我认为我们不能定义构造函数并拥有任何枚举方法。

我发现我们可以在下面的 Swift 代码中有类似的结构,但不能有任何方法。

class Job {
    class Store {
        let salary : Int
        init(int salary) {
            self.salary = salary
        }
    }
    class var NINJA: Store{
        return Store(3000000)
    }
    class var SAMURAI: Store{
        return Store(4000000)
    }
}
// Job.NINJA.salary

当然,我知道 Swift 枚举可以有自己的属性。

但是如果你在下面的情况下有更多的属性,我们必须在每个属性上都有这么多的开关。我认为这并不聪明。

enum Job {
    var salary: Int{
        switch self{
        case NINJA:
            return 3000000
        case SAMURAI:
            return 4000000
        }
    }
    case NINJA
    case SAMURAI
}

那么,如果你是我,在这种情况下你会如何编写你的 Swift 代码呢?

【问题讨论】:

  • 你的意思是不能给Store类添加attack()方法?
  • 不仅要定义“攻击”方法,我还要定义每个属性值接近自己的枚举元素定义。
  • 我已经更新了代码,现在它展示了如何覆盖自定义成员的方法。
  • @MitsuakiIshimoto 严肃的问题:为什么Samurai 的报酬比Ninja 高?

标签: java swift


【解决方案1】:

在 swift 中使用 struct 的示例:

struct MyEnum {

    static let TYPE1 = MyEnum(id: 1, text: "type 1")
    static let TYPE2 = MyEnum(id: 2, text: "type 2")

    let id: Int
    let text : String

    init(id:Int, text:String) {
        self.id = id
        self.text = text
    }

    func getId()->Int {
        return id;
    }

    func getText() ->String {
        return text;
    }

    static func values()->Array<MyEnum> {
        return [TYPE1,TYPE2]
    }

}

func == (left: MyEnum, right: MyEnum) -> Bool {
    return left.id == right.id
}

使用示例:

for e in MyEnum.values() {
    println(String(e.getId()) + " " + e.getText())
}

let type1 = MyEnum.TYPE1
if (type1==MyEnum.TYPE1) {
    println("is Type 1")
} else {
    println("is not Type 1")
}

控制台输出

1 type 1
2 type 2
is Type 1

【讨论】:

    【解决方案2】:

    您可以通过以下方式在 Swift 中调整 Job 类,使其行为类似于 Java 中的 enum

    class Job {
        class Store: Equatable {
            let salary: Int
            
            @private init(_ salary:Int) { // hope Swift will have private accessors one day
                self.salary = salary
            }
            
            func atack() ->() {}
    
        }
        
        class var NINJA: Store {
            class Ninja: Store {
                override func atack() ->() {
                    println("Attack with shuriken.")
                }
            }
            return Ninja(3000000)
        }
        
        class var SAMURAY: Store {
            class Samuray: Store {
                override func atack() ->() {
                    println("Attack with sword.")
                }
            }
            return Samuray(4000000)
        }
        
        class func CUSTOM(salary: Int) -> Store {
            return Store(salary)
        }
    }
    
    func == (lhs: Job.Store, rhs: Job.Store) -> Bool {
        return lhs.salary == rhs.salary
    }
    

    用法示例:

    var ninja = Job.NINJA
    var samuray = Job.SAMURAY
    var custom = Job.CUSTOM(23)
    
    if (ninja == samuray) {
        println("Impossible")
    } else {
        println("OK")
    }
    
    if (ninja == Job.NINJA) {
        println("Ninja salary: \(ninja.salary)")
    } else {
        println("Impossible")
    }
    
    println("Object salary: \(Job.SAMURAY.salary)")
    samuray.atack()
    

    操场上的输出:

    好的

    忍者工资:3000000

    对象工资:4000000

    用剑攻击。

    顺便说一句:如果您需要比较工资值,您可以在Store 类中实现Comparable 接口。对排序很有用。

    【讨论】:

    • 你需要重写 attack() 方法,所以没有子类化就没有办法做到这一点。而且 Swift 中没有匿名类,所以我们不能像在 Java 中那样进行就地覆盖。
    • 好! (除了 NINJA 的类 = Job.Store)
    猜你喜欢
    • 2011-08-20
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多