[swift-users] Subtract a set of a subclass?

Jordan Rose jordan_rose at apple.com
Thu Sep 1 17:55:20 CDT 2016


> On Sep 1, 2016, at 15:44, Zhao Xin via swift-users <swift-users at swift.org> wrote:
> 
> Hi Nick,
> 
> Glad to help.
> 
> but when using third party classes I don’t know if the hash values are comparable
> 
> You can create an extension with a convenient init(:), which creates a new instance of  the super class basing on the instance of the sub class. That will guarantee the subtraction. Below code works in Xcode 7.3.1 with Swift 2.2.
> 
> import Foundation
> 
> func ==(lhs: Foo, rhs: Foo) -> Bool {
>     return lhs.id == rhs.id
> }
> 
> class Foo:Hashable {
>     let id:Int
>     var hashValue: Int {
>         return id
>     }
>     
>     required init(_ id:Int) {
>         self.id = id
>     }
> }
> 
> class Bar:Foo {
>     override var hashValue: Int {
>         return id * 5
>     }
> }
> 
> var fooSet:Set<Foo> = [Foo(10), Foo(9), Foo(8), Foo(7)]
> var barSet:Set<Bar> = [Bar(8), Bar(7), Bar(6), Bar(5)]
> 
> //fooSet.subtract(barSet) // error: cannot invoke 'subtract' with an argument list of type '(Set<Bar>)'
> fooSet = fooSet.subtract(barSet as Set<Foo>) // works, but not what we want
> fooSet.forEach { print("\($0.dynamicType), id:\($0.id)") }
> /*
>  Foo, id:7
>  Foo, id:10
>  Foo, id:9
> */

This isn't really a sensible thing to do. The rules for Hashable require that `a == b` implies `a.hashValue == b.hashValue`, and `a.hashValue != b.hashValue` implies `a != b`. If you break these rules you're going to have problems no matter what static types you're using.

Upcasting from Set<Bar> to Set<Foo> is the most concise way to solve this problem.

Jordan

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160901/946439b7/attachment.html>


More information about the swift-users mailing list