logo サブスレッド

SwiftのProtocol型に対して同一インスタンスかどうか比較する

はじめに

しみずです。どうぞよろしく。

先日、健康診断の結果が初めて再検査になってしまいました。
今まではほぼオールAだったのに。年は取りたくないもんです。

今回はSwiftについてです。
Swiftでは同一インスタンスかどうかを比較するために === 演算子を使用しますが
これを使って Protocol型の変数と同一インスタンスを比較する際にビルドエラーが出てしまったので
解決方法を書いていきたいと思います。

確認環境

Xcode 7.0.1
Swift 2

NGパターン

まずは、ビルドエラーが出てしまったパターンです。

protocol HogeProtocol {
    func fuga()
}

class Hoge: HogeProtocol {
    func fuga() {
        // 実装
    }
}

class Main {
    func main() {
        let hoge = Hoge()
        let p: HogeProtocol = hoge

        if hoge === p {  // ← ここでエラーがでる
            // 何かの処理
        }
    }
}

このように、hoge と protocol 変数を比較しようとすると

Binary operator '===' cannot be applied to operands of type 'Hoge' and 'HogeProtocol'

というビルドエラーになってしまいます。

OKパターン

このビルドエラーの原因は、 === 演算子が AnyObject 同士の比較を要求しているからです。
class の方は AnyObject となりますが、protocol の方は AnyObject ではないため、このようなエラーが表示されます。
これを解決するには、この protocol は AnyObject を保証するよ。という事を教えてあげれば良いです。

protocol HogeProtocol: AnyObject {  // ← AnyObject 指定することでインスタンスが同一かを比較できるようになる
    func fuga()
}

class Hoge: HogeProtocol {
    func fuga() {
        // 実装
    }
}

class Main {
    func main() {
        let hoge = Hoge()
        let p: HogeProtocol = hoge

        if hoge === p {  // ← エラーが消える
            // 何かの処理
        }
    }
}

おわりに

インスタンスが同一かの比較をするシーンはたまにあると思いますので
覚えておくと便利そうですね。

現在の位置:サブスレッド ホーム > 技術ブログ > SwiftのProtocol型に対して同一インスタンスかどうか比較する