Comparable / Hashable / Equatable
| 対応: | Swift 1.0(2014) |
|---|
Swiftには型の同値判定・大小比較・ハッシュ化を可能にする標準プロトコル(『Equatable』『Comparable』『Hashable』)が用意されています。
プロトコル一覧
| プロトコル | 概要 |
|---|---|
| Equatable | == 演算子による同値判定を可能にします。 |
| Comparable | Equatable を継承し、< 演算子による大小比較を可能にします。<= / > / >= は自動生成されます。 |
| Hashable | Equatable を継承し、Set や Dictionary のキーとして使えるようにします。 |
| Identifiable | 一意の id プロパティを持つことを表します。SwiftUI でよく使います。 |
サンプルコード
sample_comparable_hashable.swift
// Equatable: 同値判定
struct Point: Equatable {
var x: Double
var y: Double
// == を実装(自動合成も可能だが明示的に書く例)
static func == (lhs: Point, rhs: Point) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y
}
}
let p1 = Point(x: 1.0, y: 2.0)
let p2 = Point(x: 1.0, y: 2.0)
let p3 = Point(x: 3.0, y: 4.0)
print("p1 == p2: \(p1 == p2)")
print("p1 == p3: \(p1 == p3)")
// Comparable: 大小比較
struct Fighter: Comparable {
let name: String
let power: Int
// < だけ実装すれば <= / > / >= は自動生成
static func < (lhs: Fighter, rhs: Fighter) -> Bool {
return lhs.power < rhs.power
}
}
let fighters = [
Fighter(name: "孫悟空", power: 9000),
Fighter(name: "ベジータ", power: 8500),
Fighter(name: "ピッコロ", power: 3000)
]
let sorted = fighters.sorted()
for f in sorted {
print("\(f.name): \(f.power)")
}
// Hashable: Set・Dictionary のキーに使用
struct Color: Hashable {
let r: Int, g: Int, b: Int
}
var colorSet: Set<Color> = [
Color(r: 255, g: 0, b: 0),
Color(r: 0, g: 255, b: 0),
Color(r: 255, g: 0, b: 0) // 重複は除去される
]
print("色の種類: \(colorSet.count)")
swift comparable_hashable.swift p1 == p2: true p1 == p3: false ピッコロ: 3000 ベジータ: 8500 孫悟空: 9000 色の種類: 2
概要
struct や enum の全プロパティが『Equatable』『Hashable』に準拠していれば、準拠するだけで自動合成(synthesized conformance)が使えます。== や hashValue の実装を省略できます。
『Comparable』は『<』演算子のみ実装すれば、残り(<=, >, >=)はコンパイラが自動生成します。Hashable に準拠する型は == が等しければ hashValue も等しくなければなりません(Hashable の契約)。
プロトコルの基本についてはprotocol の基本 / 準拠を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。