Rust で TDD Boot Camp （課題3:「閉区間と開区間」）generics, overload


以下ページの転載になります。ご了承ください。

[Rustを0から学んでみた 〜Part.3〜 generics（で、オーバーロード） 編（TDD Boot Camp 課題3「閉区間と開区間」） - Yuto Hongo Portfolio](https://hongo.dev/blog/learn-rust-part3-generics-trait-overload)

---


「TDDBCの課題をRustで実施し、言語仕様を学んでいこう！」というシリーズの記事です。


- [TDD Boot Camp(TDDBC) - TDDBC仙台03/課題](http://devtesting.jp/tddbc/?TDDBC%E4%BB%99%E5%8F%B003%2F%E8%AA%B2%E9%A1%8C)
- [TDD Boot Camp(TDDBC) - TDDBC仙台03/課題用語集](http://devtesting.jp/tddbc/?TDDBC%E4%BB%99%E5%8F%B003%2F%E8%AA%B2%E9%A1%8C%E7%94%A8%E8%AA%9E%E9%9B%86)



今までの記事は以下となっています。


- [Rustを0から学んでみた 〜Part.0〜 準備 / 概要 編](https://hongo.dev/blog/learn-rust-part0-introduction-and-setup)
- [Rustを0から学んでみた 〜Part.1〜 struct, impl / テストコードの基礎 編（TDD Boot Camp 課題1「閉区間」）](https://hongo.dev/blog/learn-rust-part1-struct-impl-test)
- [Rustを0から学んでみた 〜Part.2〜 trait / modの管理方法 編（TDD Boot Camp 課題2「開区間」）](https://hongo.dev/blog/learn-rust-part2-trait-module)


---


[<u>ひとことで言うとこんな記事</u>]


以下を学ぶ事ができます。


- オーバーロード機能が無いRustは、ジェネリックを利用したトレイトを準備することで実現する

---


[<u>目次</u>]

- 課題3： 閉区間と開区間
- __学んだこと：関数のオーバーロードがないRustでの実装は、ジェネリクスを利用したトレイトにて実現__
- 今回の実装の Pull Request
- 次回：TDDBC「課題4：閉区間／開区間への機能追加」 実施予定



---



## 課題3： 閉区間と開区間

### 課題3-1

- 閉区間と開区間と等しいか（equals）判定

### 課題3-2

- 閉区間と開区間と接続しているか（isConnectedTo）判定

## 学んだこと：関数のオーバーロードがないRustでの実装は、ジェネリクスを利用したトレイトにて実現


課題3と課題1,2を見てみると、 __「同じメソッド名で拡張しなはれ」__ と言っているのが自明であります。


Scalaなんかでは、同じメソッド名だとしても引数が違うものを定義するだけの簡単な作業ですが、 __Rustにはオーバーロード機能がございません__ 。

<u>scalaでの例</u>

```scala
def hoge(i: Int){
	// 実際の処理
}

def hoge(s: String){
	// 実際の処理
}
```

Rustで同じようなことを記述すると __`error[E0201]: duplicate definitions with name`と言われてコンパイルエラー__ です。


今回は、以下のrustのドキュメントを元に __"ジェネリクス"を用いた方法__ で実装していきたいと思います。


> トレイトにジェネリックな引数があると、 毎回ジェネリックな型引数の具体的な型を変更してある型に対して複数回実装できるということです。
> 
> 引用： [高度なトレイト - The Rust Programming Language](https://doc.rust-jp.rs/book/second-edition/ch19-03-advanced-traits.html#a%E9%96%A2%E9%80%A3%E5%9E%8B%E3%81%A7%E3%83%88%E3%83%AC%E3%82%A4%E3%83%88%E5%AE%9A%E7%BE%A9%E3%81%AB%E3%81%8A%E3%81%84%E3%81%A6%E3%83%97%E3%83%AC%E3%83%BC%E3%82%B9%E3%83%9B%E3%83%AB%E3%83%80%E3%83%BC%E3%81%AE%E5%9E%8B%E3%82%92%E6%8C%87%E5%AE%9A%E3%81%99%E3%82%8B)


### 実装

実際のコードは以下です

- [range.rs](https://github.com/h0ng0yut0/tddbc-rust-practice/blob/785bc8904518060dea5724ca8b6c4cc4b2694346/src/range.rs)
- [closed_range.rs](https://github.com/h0ng0yut0/tddbc-rust-practice/blob/785bc8904518060dea5724ca8b6c4cc4b2694346/src/range/closed_range.rs)


※後日パターン不備で、bugfixあげてます
[is_connected_to パターン不備 #4](https://github.com/h0ng0yut0/tddbc-rust-practice/pull/4)


<u>range.rs</u>

```rust
// 自身しか関わらないもの
pub trait SelfRange {
  fn new(lower: i8, upper: i8) -> Self;
  fn to_string(&self) -> String;
  fn contains(&self, number: i8) -> bool;
}

// 他のstructが絡むもの
pub trait MultiRange<T> {
  fn equals(&self, range: &T) -> bool;
  fn is_connected_to(&self, range: &T) -> bool;
}
```

<u>closed_range.rs</u>

```rust
// 他のStructが絡む部分の実装

impl MultiRange<OpenRange> for ClosedRange {
  fn equals(&self, _: &OpenRange) -> bool {
    false
  }

  fn is_connected_to(&self, range: &OpenRange) -> bool {
    match range {
      r if self.lower < r.upper && r.upper < self.upper => true,
      r if self.lower < r.lower && r.lower < self.upper => true,
      _ => false,
    }
  }
}

impl MultiRange<ClosedRange> for ClosedRange {
  fn equals(&self, closed_range: &ClosedRange) -> bool {
    self.lower == closed_range.lower && self.upper == closed_range.upper
  }

  fn is_connected_to(&self, range: &ClosedRange) -> bool {
    match range {
      r if self.lower <= r.upper && r.upper <= self.upper => true,
      r if self.lower <= r.lower && r.lower <= self.upper => true,
      _ => false,
    }
  }
}
```

上記のように、`equals()`と`is_connected_to`に関して、引数が OpenRange.ver と  ClosedRange.ver 共に実装することが可能となっています。


## 今回の実装の Pull Request

[課題３：閉区間と開区間 by h0ng0yut0 · Pull Request #3 · h0ng0yut0/tddbc-rust-practice](https://github.com/h0ng0yut0/tddbc-rust-practice/pull/3)

## 次回：TDDBC「課題4：閉区間／開区間への機能追加」 実施予定

今回は、ジェネリクスとその利用方法、またその1例としてのオーバーロード を学べました。次回の課題は何が学べるのか楽しみです。


- [TDD Boot Camp(TDDBC) - TDDBC仙台03/課題](http://devtesting.jp/tddbc/?TDDBC%E4%BB%99%E5%8F%B003%2F%E8%AA%B2%E9%A1%8C)
- [TDD Boot Camp(TDDBC) - TDDBC仙台03/課題用語集](http://devtesting.jp/tddbc/?TDDBC%E4%BB%99%E5%8F%B003%2F%E8%AA%B2%E9%A1%8C%E7%94%A8%E8%AA%9E%E9%9B%86)

---



[<u>これから読んでみたい本</u>]
https://amzn.to/34pexMw


---

最後までお読みいただき、誠にありがとうございます。様々なことを学んでいきたいと思っていますので、内容やソースコード等のアドバイスいただけると幸いです。