今年の言語はRust その５８

# 今年の言語はRust その５８

Rustを学びます

Rustの日本語ドキュメント 2nd Edition
https://doc.rust-jp.rs/book/second-edition/

オリジナル(英語)
https://doc.rust-lang.org/book/


## 実行環境

```sh
$ cargo -V
cargo 1.33.0 (f099fe94b 2019-02-12)

$ rustup -V
rustup 1.17.0 (069c88ed6 2019-03-05)

$ rustc --version
rustc 1.33.0 (2aa4c46cf 2019-02-28)

$  cat /proc/version
Linux version 4.14.97-74.72.amzn1.x86_64 (mockbuild@gobi-build-64002) 
(gcc version 7.2.1 20170915 (Red Hat 7.2.1-2) (GCC)) 
#1 SMP Tue Feb 5 20:59:30 UTC 2019

$ uname -a
Linux ip-10-100-0-8 4.14.97-74.72.amzn1.x86_64 
#1 SMP Tue Feb 5 20:59:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

$ cat /etc/\*release
NAME="Amazon Linux AMI"
VERSION="2018.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2018.03"
PRETTY_NAME="Amazon Linux AMI 2018.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2018.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"
Amazon Linux AMI release 2018.03

```

## 19. 高度な機能

通常なら飛ばして後から考えますが、今回は全写経が目的なので、
理解朧げでもひたすら写経して進んでいきます。


### 19.3 高度なトレイト

#### 明確化のためのフルパス記法: 同じ名前のメソッドを呼ぶ

複数のトレイトや、メンバメソッドの名前が重複する場合を考えよう

```rust

trait Pilot {
  fn fly(&self);
}

trait Wizard {
  fn fly(&self);
}

struct Human;

impl Pilot for Human {
  fn fly(&self) {
    println!("This is your captain speaking.");
  }
}

impl Wizard for Human {
  fn fly(&self) {
    println!("Up!");
  }
}

impl Human {
  fn fly(&self) {
    println!("*waving arms furiously*");
  }
}


fn main () {
  let person = Human;
  person.fly();
}
```

これはHumanのflyになる.

```bash 
*waving arms furiously*
```


これを解決するには、以下のようにトレイトを指定してあげる。

```rust
fn main () {
  let person = Human;

  Pilot::fly(&person);
  Wizard::fly(&person);
  person.fly();
}
```

もう一つの例に行きます

__関連関数__ いわゆるスタティック関数?の場合かな

```rust

trait Animal {
  fn baby_name() -> String;
}


struct Dog;

impl Animal for Dog {
  fn baby_name() -> String {
    String::from("puppy")
  }
}


impl Dog {
  fn baby_name() -> String {
    String::from("Spot")
  }
}


fn main() {
  println!("A baby dog is called a {:?}", Dog::baby_name());
  println!("A baby dog is called a {:?}", <Dog as Animal>::baby_name());
}

```

```bash
A baby dog is called a "Spot"
A baby dog is called a "puppy"
```


#### スーパートレイトを使用して別のトレイト内で、あるトレイトの機能を必要する

```rust
use std::fmt;

trait OutlinePrint: fmt::Display {
  fn outline_print(&self) {
    let output = self.to_string();
    let len = output.len();

    println!("{:?}", "*".repeat(len + 4));
    println!("*{:?}*", " ".repeat(len + 2));
    println!("* {:?} *", output);
    println!("*{:?}*", " ".repeat(len + 2));
    println!("{:?}", "*".repeat(len + 4));
  }
}


struct Point {
  x:i32,
  y:i32,
}


impl OutlinePrint for Point {}


impl fmt::Display for Point {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "({}, {})", self.x, self.y)
  }
}

```


#### ニュータイプパターンを使用して外部の型に外部のトレイトを実装する

ここではVec<T>にDisplayを実装したいとする. 

タプル構造体を利用して実現します。

```rust

use std::fmt;

struct Wrapper(Vec<String>); // タプル構造体

impl fmt::Display for Wrapper {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "[{}]", self.0.join(", "))
  }
}


fn main() {
  let w = Wrapper(vec![String::from("hello"), String::from("world")]);
  println!("w={:}", w);
}
```



実践経験がないので、ほとんどぴんと来ていないが
我慢して写経を続けよう
そうすれば未来はすぐそこ

イエス！


あと、5/8にRustの最新本がでるみたいです! 気が付いてラッキー！ (現在5/7)

[実践Rust入門[言語仕様から開発手法まで] 単行本（ソフトカバー） – 2019/5/8](https://amzn.to/2VdAQ6y)

<a href="https://www.amazon.co.jp/%E5%AE%9F%E8%B7%B5Rust%E5%85%A5%E9%96%80-%E8%A8%80%E8%AA%9E%E4%BB%95%E6%A7%98%E3%81%8B%E3%82%89%E9%96%8B%E7%99%BA%E6%89%8B%E6%B3%95%E3%81%BE%E3%81%A7-%CE%BAeen/dp/4297105594/ref=as_li_ss_il?_encoding=UTF8&psc=1&refRID=KADG0R1CJZD9Y07B3P7E&linkCode=li2&tag=peace098beat-22&linkId=52fef8a307968a1010a3375899274077&language=ja_JP" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4297105594&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=peace098beat-22&language=ja_JP" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=peace098beat-22&language=ja_JP&l=li2&o=9&a=4297105594" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />

※アフェっときます