> On Mar 28, 2017, at 12:50 PM, Zhao Xin via swift-users > <swift-users@swift.org> wrote: > > Please see the code first. > > import Foundation > > class Foo:Hashable { > let value:Int > > public var hashValue: Int { return value } > public static func ==(lhs: Foo, rhs: Foo) -> Bool { > return lhs.value == rhs.value > } > > init(_ value:Int) { > self.value = value > } > } > > let fooSetA:Set = [Foo(8), Foo(9)] > let fooSetB:Set = [Foo(9), Foo(10)] > let fooResultC = fooSetA.intersection(fooSetB) // {{value 9}} > let fooResultD = fooSetA.subtracting(fooSetB) // {{value 8}} > > > class Bar:NSObject { > let value:Int > > override public var hashValue: Int { return value } > public static func ==(lhs: Bar, rhs: Bar) -> Bool { > return lhs.value == rhs.value > } > > init(_ value:Int) { > self.value = value > } > } > > let barSetA:Set = [Bar(8), Bar(9)] > let barSetB:Set = [Bar(9), Bar(10)] > let barResultC = barSetA.intersection(barSetB) // Set([]) > let barResultD = barSetA.subtracting(barSetB) // {{NSObject, value 9}, > {NSObject, value 8}} > > > Behaviors of `func intersection(Set<Set.Element>)` and `func > subtracting(Set<Set.Element>)` were different between normal Swift class and > NSObject subclasses. I had thought they should be the same. It seemed that > Set<NSObject> relied on addresses of NSObject instances instead of their > hashValues. That made the Set useless.
This is a known issue—when you redeclare `static func ==` inside Bar, that does not override `NSObject.==`, and moreover *cannot*, since overriding `NSObject.==` requires an implementation that accepts two NSObjects. We ought to consider this an error, or at least a warning. NSObject conforms to Equatable on behalf of all its subclasses by implementing `==` in terms of `isEqual:` and `hashValue` in terms of `hash`. Even though you can override `hashValue` for Swift, it's probably still safer to override `hash` and `isEqual` in order to get common behavior between ObjC and Swift, since ObjC will not use Swift's conformances. Perhaps the NSObject implementation of `hashValue` should be final to help with this. -Joe _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users