【swift】RxDataSourcesでEquatableに準拠せさるときに！

## はじめに
`RxSwift`で、TableViewの差分更新を行うときに、`RxDataSources`を使うことがあると思います。
`RxDataSorces`の詳細に関しては、[公式レポジトリー](https://github.com/RxSwiftCommunity/RxDataSources)を参照してださい....

## RxDataSources
`RxTableViewSectionedAnimatedDataSource`を使う場合、`AnimatableSectionModelType`に準拠したmodelを用意する必要があります。
実装としては
1. `RxTableViewSectionedAnimatedDataSource`で`cell`や`section`などの`tableView`の設定を`AnimatableSectionModelType`に準拠したmodelを用いて行う
2. `AnimatableSectionModelType`に準拠した`Observable`な`model`を`tableView`に`bind`する

詳細はサンプルコードをみてください。（[RxDataSources/Example/Example1_CustomizationUsingTableViewDelegate.swift](https://github.com/RxSwiftCommunity/RxDataSources/blob/master/Example/Example1_CustomizationUsingTableViewDelegate.swift)）

## Equatableへの準拠
上記の実装のように、`RxDataSources`を使うには`AnimatableSectionModelType`に準拠したmodelを用意する必要があり、準拠する`AnimatableSectionModelType`のprotocolは下記のようになっています。

```AnimatableSectionModelType.swift
public protocol AnimatableSectionModelType {
    : SectionModelType
    , IdentifiableType where Item: IdentifiableType, Item: Equatable {
}
```

また、`AnimatableSectionModelType`が準拠している`SectionModelType`は下記の実装になっています。

```SectionModelType.swift
public protocol SectionModelType {
    associatedtype Item

    var items: [Item] { get }

    init(original: Self, items: [Item])
}
```

`SectionModelType`のGenericsの`Item`は`IdentifiableType`と`Equatable`に準拠する必要があります！！


## 困ったこと：`Equatable`に準拠できない！？

`NSObject`に準拠したmodelを`Equatable`に準拠させようとしていた。。。

```sample.swift
class TestModel: NSObject { 
    let id: Int
}

extension TestModel: Equatable {
    static func == (lhs: TestModel, rhs: TestModel) -> Bool {
        return lhs.id == rhs.id
    }
}
```

下記のコンパイルエラーがでる
`Redundant conformance of 'TestModel' to protocol 'Equatable'`

自作したクラス`TestModel`を`Equatable`に準拠したつもりはないのに、なぜ準拠済みなのかわからない？？


## 理由：NSObjectがすでにEquatableである！
[NSObjectのドキュメントのConforms](https://developer.apple.com/documentation/objectivec/nsobject#conforms-to)にあるように、`NSObject`はすでに`Equatable`に準拠しています。そのため、上記の実装だと既に準拠だとエラーが出ます。
ちなみに、`NSObject`の`Equatable`は参照しているポインタが同じかどうかをチェックしています。

superクラスの比較でなく、subclassを用いて比較させたい場合は、subclassにクラスメソッドを実装することで、subclassでの比較を行うことができます。

```swift
extension TestModel {
    static func ==(lhs: TestModel, rhs: TestModel) -> Bool {
        return lhs.id == rhs.id
    }
}
```

## swift4.1からの`Equatable`
ここからは上記のエラーとは異なりますが、`Equatable`なクラスを実装するときの追加の話です。
swift4.1からは、より簡単に`Equatable`の実装を行うことができます。

swift4.1で実装された[Synthesizing Equatable and Hashable conformance](https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md)によって、コンパイラーが自動的に`Equatable`と`Hashable`に準拠させてくれます。

条件としては、
*`Equatable`の実装する`クラス` or `enum` or `struct`で定義されている`stored instance property`と`associated value`が、`Equatable`に準拠している場合に、`static func == (lhs: Self, rhs: Self) -> Bool`が暗黙的に実装されます。*

実装例が下記になります！
swift4.0の場合

```test.swift
struct Person: Equatable {
    let firstName: String
    let lastName: String
    
    static func == (lhs: Person, rhs: Person) -> Bool {
        return lhs.firstName == rhs.firstName &&
               lhs.lastName == rhs.lastName &&
    }
}
```

swift4.1の場合（暗黙的に`Equatable`に準拠できる！！）

```test.swift
struct Person: Equatable {
    let firstName: String
    let lastName: String
}
```


上記のように`Equatable`に準拠する際に、大量のコードを記述する必要がなくなって、より`Equatable`が使いやすくなり、`RxDataSources`も使いやすくなったと思います！！！