LoginSignup
41
18

Swift の Equatable プロトコルを基礎から

Last updated at Posted at 2019-05-27

この記事は何?

前回CustomStringConvertible プロトコルについて調べました。
今回は Equatable プロトコルです。
これは、オブジェクトが比較できることを保証するようです。

Swiftを基礎から学ぶには
自著、工学社より発売中の「まるごと分かるSwiftプログラミング」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。

実行環境

Xcode10.2.1
Swift5.x

ハンズオン

Playground でコードを実行して確認しました。

こんなカスタム型があったとして

フルーツを表現する構造体 Fruit です。
nameemoji プロパティがあります。

フルーツを表現する構造体
struct Fruit {
    var name:  String
    var emoji: String
}

let apple  = Fruit(name: "Apple",  emoji: "🍎")
let banana = Fruit(name: "Banana", emoji: "🍌")

apple オブジェクトと Banana オブジェクトは違うフルーツです。
同じかどうかを比べてみましょう。

リンゴとバナナを比較する
apple == banana    // 比較した結果は...

false が返ってきそうなものですが...
スクリーンショット 2019-05-27 22.28.59.png
エラーメッセージが表示されました。
Binary operator '==' cannot be applied to two 'Fruit' operands だそうです。
「2つのFruit 型の項には2項演算子 == が適用できません」的なことを言っています。

プロトコルに準拠する

オブジェクト同士が 同じかどうか を比較できることを保証するには、Equatable プロトコルに準拠させます。

比較可能になったFruit型
struct Fruit: Equatable {
    var name:  String
    var emoji: String
}

すると、エラーが消えます。

Fruit型オブジェクトの比較
apple == Banana    // false

予想通りの結果が得られました。
どうやら、型を Equatable プロトコルに準拠させると すべてのメンバープロパティが同じかどうか を自動的に比較してくれているようです。

比較の条件を制御する

こんなフルーツがあったとします。

2種のオレンジ
let vOrange = Fruit(name: "Valencia Orange",  emoji: "🍊")
let mOrange = Fruit(name: "Mandarine Orange", emoji: "🍊")

vOrange == mOrange    // false

同じかどうか比較すると、false になります。
でも、これらのオレンジは品種こそ違いますが、同じフルーツとして扱いたい 気がします。

  • name プロパティは無視して...
  • emoji プロパティだけを比較

することができれば良さそうです。

== 演算子を実装する

== 演算子は、比較するときに使いますね。
静的メソッドとして実装することで、== 演算子の挙動を型独自にカスタムできます。
emoji プロパティ同士だけを比較した結果を返すようにしましょう。

struct Fruit: Equatable {
    var name: String
    var emoji: String
    
    // 自身と同じ型を2つ受け取る静的メソッド
    static func == (lhs: Fruit, rhs: Fruit) -> Bool{
        return lhs.emoji == rhs.emoji
    }
}

ちなみに、== メソッドの引数名 lhsrhs はそれぞれ left-hand sideright-hand side の略称です。
引数名はなんでも構わないようですが、標準ライブラリなどの様式に倣いました。

もう一度、2つのオレンジを比較してみると...

オレンジの比較PART2
vOrange == mOrange    // true

結果が変化しました。
品種が違えど、オレンジ同士なので true を返しています。

POP

数年前のWWDC(World Wide Developers Conference) で、Protocol-oriented Programming というコンセプトが提唱されたことがありました。
どうやら、Swiftプログラミングではプロトコルを理解しておくことが重要なようです。
あと、__ジェネリクス__ですか。
少しずつ、基礎から勉強していきたいと思います。

41
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
41
18