Swift Equatable Protocol


85

ฉันกำลังทำบทช่วยสอนนี้สำหรับ Swift: https://www.raywenderlich.com/125311/make-game-like-candy-crush-spritekit-swift-part-1และเจอรหัสนี้:

func == (lhs: Cookie, rhs: Cookie) -> Bool {
    return lhs.column == rhs.column && lhs.row == rhs.row
}

ฉันเขียนตามนั้น แต่ Xcode ให้ข้อผิดพลาดเหล่านี้:

Consecutive declarations on a line must be separated by ';'
Expected declaration operators are only allowed at global scope

ฉันพบรหัสนี้จากเอกสารของ apple: https://developer.apple.com/documentation/swift/equatable

ซึ่งคล้ายกับที่ผมเขียนมาก. มีอะไรผิดปกติ ดูเหมือนว่าจะเป็นข้อบกพร่องสำหรับฉัน ฉันใช้ Xcode 6 Beta 2

แก้ไข:

นี่คือคลาสคุกกี้ทั้งหมดของฉัน:

class Cookie: Printable, Hashable {
    var column: Int
    var row: Int
    let cookieType: CookieType
    let sprite: SKSpriteNode?
    
    init(column: Int, row: Int, cookieType: CookieType) {
        self.column = column
        self.row = row
        self.cookieType = cookieType
    }
    
    var description: String {
        return "type:\(cookieType) square:(\(column),\(row))"
    }
    
    var hashValue: Int {
        return row * 10 + column
    }
    
    func ==(lhs: Cookie, rhs: Cookie) -> Bool {
        return lhs.column == rhs.column && lhs.row == rhs.row
    }
}

โค้ดก่อนคำสั่งนั้นคืออะไร? มันทำงานได้ดีสำหรับฉันด้วยตัวเอง
Connor

ฉันเพิ่มทั้งชั้นเรียนในคำอธิบาย
แอดดิสัน

8
"ผู้ดำเนินการประกาศได้รับอนุญาตในขอบเขตทั่วโลกเท่านั้น" สวยยี้ชัดเจน นี่เป็นหนึ่งในข้อความแสดงข้อผิดพลาดของคอมไพเลอร์ที่ดีกว่าของ Swift!
แมตต์

1
คุณสามารถโอเวอร์โหลดตัวดำเนินการในขอบเขตไฟล์เท่านั้น
holex

2
คุณต้องย้ายfunc ==(lhs: Cookie, rhs: Cookie) -> Bool {...}ออกจากคลาส Cookie !!
Hlung

คำตอบ:


145

ย้ายฟังก์ชันนี้

func == (lhs: Cookie, rhs: Cookie) -> Bool {
    return lhs.column == rhs.column && lhs.row == rhs.row
}

นอกคลาสคุกกี้ วิธีนี้มีเหตุผลเนื่องจากจะแทนที่โอเปอเรเตอร์ == ที่ขอบเขตส่วนกลางเมื่อใช้กับคุกกี้สองตัว


3
ฉันต้องการเพิ่มว่าใน xCode 6.3.2 และ swfit 1.2 func == ต้องอยู่หลังคลาสหรือนิยามโครงสร้าง แม้แต่การเพิ่มประโยคง่ายๆเช่น "var a = 1" จะทำให้คอมไพเลอร์ผิดพลาดกลับมา
fangmobile

2
ฉันไม่เคยคิดที่จะใส่มันนอกชั้นเรียน! เรียกว่าอะไร? หาใน google ได้อย่างไร
rr1g0

1
มีคำอธิบายเกี่ยวกับสาเหตุที่ตัวดำเนินการโอเวอร์โหลดอยู่ในขอบเขตทั่วโลกแม้ว่าจะมีการหารือเกี่ยวกับการเปลี่ยนแปลงที่เป็นไปได้เพื่อให้การใช้งานตัวดำเนินการอยู่ในประเภท

32

SWIFT 2:

เช่นเดียวกับใน swift 2 NSObjectแล้วEquatableคุณไม่ต้องการความสอดคล้องที่ด้านบนดังนั้นจึงเป็นเช่นนั้น

class Cookie: NSObject {
    ...

}

และคุณต้องแทนที่isEqualวิธีการเป็น

class Cookie:NSObject{
    var column: Int
    var row: Int

    //..........

    override func isEqual(object: AnyObject?) -> Bool {
        guard let rhs = object as? Cookie else {
            return false
        }
        let lhs = self

        return lhs.column == rhs.column
    }

}

isEqualวิธีการเวลานี้อยู่ในชั้นเรียน :)

แก้ไขสำหรับ SWIFT 3:เปลี่ยนวิธีนี้เป็น

override func isEqual(_ object: AnyObject?) -> Bool {
        guard let rhs = object as? Cookie else {
            return false
        }
        let lhs = self

        return lhs.column == rhs.column
    }

6

การทำให้คลาสเป็น NSObject แก้ปัญหาที่เท่าเทียมกันสำหรับฉัน ...

class Cookie: NSObject {
...
}

(ได้รับคำแนะนำจากบทช่วยสอนสำหรับเด็กฝึกงาน iOS)


1
นั่นก็เป็นเพราะการดำเนินการดังต่อไปนี้ NSObject บนเส้น 70 ของ extension NSObject : Equatable, HashableswiftDoc
Adrian Sluyters
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.