この記事は何?
前回は CustomStringConvertible
プロトコルについて調べました。
今回は Equatable
プロトコルです。
これは、オブジェクトが比較できることを保証するようです。
Swiftを基礎から学ぶには
自著、工学社より発売中の「まるごと分かるSwiftプログラミング」をお勧めします。変数、関数、フロー制御構文、データ構造はもちろん、構造体からクロージャ、エクステンション、プロトコル、クロージャまでを基礎からわかりやすく解説しています。
実行環境
Xcode10.2.1
Swift5.x
ハンズオン
Playground でコードを実行して確認しました。
こんなカスタム型があったとして
フルーツを表現する構造体 Fruit
です。
name
と emoji
プロパティがあります。
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
が返ってきそうなものですが...
エラーメッセージが表示されました。
Binary operator '==' cannot be applied to two 'Fruit' operands だそうです。
「2つのFruit
型の項には2項演算子 ==
が適用できません」的なことを言っています。
プロトコルに準拠する
オブジェクト同士が 同じかどうか を比較できることを保証するには、Equatable
プロトコルに準拠させます。
struct Fruit: Equatable {
var name: String
var emoji: String
}
すると、エラーが消えます。
apple == Banana // false
予想通りの結果が得られました。
どうやら、型を Equatable
プロトコルに準拠させると すべてのメンバープロパティが同じかどうか を自動的に比較してくれているようです。
比較の条件を制御する
こんなフルーツがあったとします。
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
}
}
ちなみに、==
メソッドの引数名 lhs
と rhs
はそれぞれ left-hand side と right-hand side の略称です。
引数名はなんでも構わないようですが、標準ライブラリなどの様式に倣いました。
もう一度、2つのオレンジを比較してみると...
vOrange == mOrange // true
結果が変化しました。
品種が違えど、オレンジ同士なので true
を返しています。
POP
数年前のWWDC(World Wide Developers Conference) で、Protocol-oriented Programming というコンセプトが提唱されたことがありました。
どうやら、Swiftプログラミングではプロトコルを理解しておくことが重要なようです。
あと、__ジェネリクス__ですか。
少しずつ、基礎から勉強していきたいと思います。