生锈特质状态

时间:2014-04-08 11:21:41

标签: struct rust code-duplication traits

我将从这个怪物" Monster"开始。来自Rust for Rubyist的代码:

trait Monster {
    fn attack(&self);
    fn new() -> Self;
}

struct IndustrialRaverMonkey {
    life: int,
    strength: int,
    charisma: int,
    weapon: int,
}

struct DwarvenAngel {
    life: int,
    strength: int,
    charisma: int,
    weapon: int,
} ...
impl Monster for IndustrialRaverMonkey { ...
impl Monster for DwarvenAngel { ...

我担心代码重复。在Java中,我将创建定义attack方法和基类的接口,其中包含所有参数(lifestrengthcharismaweapon)。我将使用抽象类在C ++中做同样的事情。 我可以找到一些解决这个问题的丑陋和不直观的方法,但是有一种减少代码的好方法吗?我的意思是,保持其可扩展性和可读性。

2 个答案:

答案 0 :(得分:2)

另一种有利于合成的方法,如果需要,可以更容易地分离实现(例如,Characteristics DwarvenAngel需要额外的字段):

trait Monster {
    fn attack(&self);
}

struct Characteristics {
    life: int,
    strength: int,
    charisma: int,
    weapon: int,
}

struct IndustrialRaverMonkey {
    characteristics: Characteristics
}

struct DwarvenAngel {
    characteristics: Characteristics
}

fn same_attack(c: Characteristics) {
    fail!("not implemented")
}

impl Monster for IndustrialRaverMonkey {
    fn attack(&self) {
        same_attack(self.characteristics)
    }
}

impl Monster for DwarvenAngel {
    fn attack(&self) {
        same_attack(self.characteristics)
    }
}

或者,你可以让一个枚举代表你的怪物类型,非常类似于A.B。答案:

trait Monster {
    fn attack(&self);
}

struct Characteristics {
    life: int,
    strength: int,
    charisma: int,
    weapon: int,
}

enum Monsters {
    IndustrialRaverMonkey(Characteristics),
    DwarvenAngel(Characteristics),
}

fn same_attack(_: &Characteristics) {
    fail!("not implemented")
}

impl Monster for Monsters {
    fn attack(&self) {
        match *self {
            IndustrialRaverMonkey(ref c) => same_attack(c),
            DwarvenAngel(ref c)          => same_attack(c)
        }
    }
}

答案 1 :(得分:0)

你会认为这样的事情是可接受的解决方案吗?

trait Actor {
    fn attack(&self);
}

enum MonsterId {
    IndustrialRaverMonkey,
    DwarvenAngel
}

struct Monster {
    life: int,
    strength: int
}

impl Monster {
    fn new(id: MonsterId) -> Monster {
        match id {
            IndustrialRaverMonkey => 
            Monster { life: 12, strength: 8 },

            DwarvenAngel => 
            Monster { life: 18, strength: 12 }
        }
    }
}


impl Actor for Monster { 
    fn attack(&self) {}
}

更新了一个更好的例子。