SwiftのプロトコルにEquatableを実装

1701 ワード

作者:Natasha The Robot,原文リンク,原文日付:2016-07-25訳者:Lanford 3_3;校正:千葉知風;原稿:CMB
先週iXSDevCampDCに出席し、@ayanonagonのテストに関する講演に参加しました.サンプルコードを入手することができます.
驚いたことに、彼女はテストの目的でプロトコル(protocol)のためにデフォルトのEquatableを実現しました.
protocol Rectangle: Equatable {
    var width: Double { get }
    var height: Double { get }
}

//  
//  
func ==(lhs: T, rhs: T) -> Bool {
    return lhs.width == rhs.width &&
        rhs.height == lhs.height
}

驚いたのは、あるプロトコルに従うすべてのオブジェクトにこのようなデフォルトの実装を持たせるとは思わなかったからです.これは確かに私を思考に陥れた!もちろん、Ayakaの例にとっては合理的です.彼女は完全にテストの目的でこのようなコードを追加しました.
しかし、私はこのようなやり方を考えて、もっと深く考えた後、発生する可能性のあるバグを見ました.このプロトコルの値に従って他の属性がある場合はどうなりますか?デフォルトの等化判定は、予想通りに動作しません.例を挙げます.
struct ColorfulRectangle: Rectangle {
    let width: Double
    let height: Double
    let color: UIColor
}

let blueRectangle = ColorfulRectangle(width: 10, height: 10, color: .blueColor())
let redRectangle = ColorfulRectangle(width: 10, height: 10, color: .redColor())

//  , 
blueRectangle == redRectangle // true

もちろん、ColorfulRectangleが独自のEquatableを実現すれば、このバグは修復されます.
func ==(lhs: ColorfulRectangle, rhs: ColorfulRectangle) -> Bool {
    return lhs.width == rhs.width &&
        rhs.height == lhs.height &&
        rhs.color == lhs.color
}

//  ,  false
blueRectangle == redRectangle // false

しかし問題は、これが漏れやすく、特にこのEquatableが実現しなかったとしても、コンパイラは警告を出さないことです.
したがって,プロトコルレベルでデフォルトのEquatableを追加することはかなり有用であるが,危険である.責任ある態度で使いましょう!
私と一緒に9月1日-2日にニューヨーク城で開催されるSwiftコミュニティフェスティバルに参加しましょう.特典コードNATASHATHEROBOTを使用して$100の割引を受けます!
本文はSwiftGG翻訳グループから翻訳して、すでに作者の翻訳の授権を得て、最新の文章は訪問して下さいhttp://swift.gg.