> 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

Reply via email to