複数のトレイト境界を持つトレイトオブジェクトの取り扱い

# はじめに
複数のトレイト境界を持つトレイトオブジェクトを取り扱ったので忘備録として投稿致します。
ソースコードは[gist](https://gist.github.com/morimolymoly/51ee0556a4d166a8ce75968f6f0ca0a2)にあります。

# やりたいこと
複数のトレイトを実装した型を共通したインターフェイスで扱いたい
# 問題

例えば以下のようなトレイト`A`,`B`がある場合、

```rust
trait A {
    fn fn_a(&self) {
        println!("fna");
    }
}

trait B {
    fn fn_b(&self) {
        println!("fnb");
    }
}
```

以下のように、合成したトレイトオブジェクトは使用できません。

```rust
fn main() {
    let mut st_vec: Vec<Box<dyn A + B>> = Vec::new();
    st_vec2.push(Box::new(St1{}));
    st_vec2.push(Box::new(St2{}));
    
    for s in st_vec2.iter() {
        s.fn_a();
        s.fn_b();
    }
}
```

# 解決

そこで、トレイト`A`、`B`を合成したトレイト`C`を導入します。

```rust
trait C: A + B {}
```

合成したトレイトと使用した例は以下のようになります。

```rust
struct St1{}
impl A for St1{}
impl B for St1{}
impl C for St1{}

struct St2{}
impl A for St2{}
impl B for St2{}
impl C for St2{}

fn main() {
    //let mut st_vec: Vec<Box<dyn A + B>> = Vec::new(); 使用できない
    let mut st_vec2: Vec<Box<dyn C>> = Vec::new();
    st_vec2.push(Box::new(St1{}));
    st_vec2.push(Box::new(St2{}));
    
    for s in st_vec2.iter() {
        s.fn_a();
        s.fn_b();
    }
}
```

# 結果
既存のトレイト`A`、`B`を合成したトレイト`C`を導入することにより合成したトレイトオブジェクトが作成できるため、インターフェイスを共通化することができました

# おまけ：発展した実装例
犬猫の生き死にはよく、オブジェクト指向を説明する際に使用されます。
今回はこれを実装することにしました。
[Github](https://github.com/morimolymoly/trait-tests)にソースコードがあります。


さて、今回扱うトレイトは以下の3つです。

```rust
trait Born {
    fn born(&mut self) -> bool;
}

trait Die {
    fn die(&mut self) -> bool;
}

trait Animal: Born + Die {
    fn is_alive(&self) -> bool;
}
```

`Born`と`Die`を持ち合わせるトレイトオブジェクトを作成するために、`Animal`オブジェクトを作成しました。

次に、`Born`、`Die`、`Animal`のトレイトを実装する構造体`Dog`、`Animal`を実装しました。

```rust
struct Dog {
    alive: Option<bool>,
    name: String,
}

impl Dog {
    fn new(name: String) -> Dog {
        Dog { name, alive: None }
    }
}

impl Animal for Dog {
    fn is_alive(&self) -> bool {
        match self.alive {
            Some(true) => {
                println!("dog[{}] is still alive!", self.name);
                true
            }
            Some(false) => {
                println!("dog[{}] is dead!", self.name);
                false
            }
            None => {
                println!("dog[{}] have not born yet!", self.name);
                false
            }
        }
    }
}

impl Born for Dog {
    fn born(&mut self) -> bool {
        if let Some(s) = self.alive {
            if s {
                println!("dog[{}] have already borned!", self.name);
                return false;
            }
            println!("dog[{}] have already died!", self.name);
            return false;
        }
        self.alive = Some(true);
        println!("dog[{}] borned!", self.name);
        return true;
    }
}

impl Die for Dog {
    fn die(&mut self) -> bool {
        if let Some(s) = self.alive {
            if s {
                self.alive = Some(false);
                println!("dog[{}] died!", self.name);
                return true;
            }
            println!("dog[{}] have already dead", self.name);
            return false;
        }
        println!("dog [{}]have not born yet!", self.name);
        return false;
    }
}

struct Cat {
    alive: Option<bool>,
    name: String,
}

impl Animal for Cat {
    fn is_alive(&self) -> bool {
    //省略
    }
}

impl Cat {
    fn new(name: String) -> Cat {
        Cat { name, alive: None }
    }
}

impl Born for Cat {
    fn born(&mut self) -> bool {
    //省略
    }
}

impl Die for Cat {
    fn die(&mut self) -> bool {
    //省略
    }
}
```

これらの構造体を一つの`Vec`で扱うことができます。型は`Vec<Box<dyn Animal>`です。

```rust
fn main() {
    let mut ani_vec: Vec<Box<dyn Animal>> = Vec::new();

    ani_vec.push(Box::new(Dog::new(String::from("taro"))));
    ani_vec.push(Box::new(Dog::new(String::from("jiro"))));
    ani_vec.push(Box::new(Dog::new(String::from("saburo"))));
    ani_vec.push(Box::new(Cat::new(String::from("nyan"))));
    ani_vec.push(Box::new(Cat::new(String::from("neko"))));
    ani_vec.push(Box::new(Cat::new(String::from("nuko"))));

    for a in ani_vec.iter_mut() {
        a.is_alive();
        a.born();
        a.is_alive();
        a.die();
        a.is_alive();
    }
}

```

以上です。