今年の言語は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

pub trait Iterator {
  type Item;

  fn next(&mut self) -> Option<Self::Item>;
}

pub struct Counter{
  count: u32,
}

impl Iterator for Counter {
  type Item = u32;

  fn next(&mut self) -> Option<Self::Item> {
    // -- snip --
  }
}

```

これまでの学習内容からは、
__ジェネリック__ を使えば？となる

```rust
pub trait Iterator<T> {
    fn next(&mut self) -> Option<T>;
}
```

ジェネリックだと、使うごとに型を指定する必要がでてくる。

関連型なら、同じ型に対してトレイト複数回実装できないからいいらしい。

後半何言ってるかわからん。

#### デフォルトのジェネリック型引数と演算子オーバーロード

```rust
use std::ops::Add;


#[derive(Debug, PartialEq)]
struct Point {
  x: i32,
  y: i32,
}

impl Add for Point {
  type Output = Point;

  fn add(self, other: Point) -> Point {
    Point {
      x: self.x + other.x,
      y: self.y + other.y,
    }
  }

}


fn main() {

  assert_eq!(Point {x:1, y:0} + Point {x:2, y:3}, Point{x:3, y:3});

}
```


Addトレイトは以下のようになっている.

RHSとはデフォルト型引数と呼ばれる。 
つまり、Addを実装する際にジェネリックを指定しなければ、
Selfと同じ型になるということ


```rust
trait Add<RHS=Self> {
    type Output;

    fn add(self, rhs: RHS) -> Self::Output;
}
```

以下の例では、実装時に別の型を使用することで、型の異なる構造体どうしを計算している。



```rust
use std::ops::Add;

struct Millimeters(u32);
struct Meters(u32);

impl Add<Meters> for Millimeters {
  type Output = Millimeters;

  fn add(self, other: Meters) -> Millimeters {
    Millimeters(self.0 + (other.0 * 1000))
  }
}

```

すごい便利！






イエス！


あと、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;" />

※アフェっときます