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

Zhao Xin owenzx at gmail.com
Thu Sep 1 18:28:15 CDT 2016


I believe if B inherits A, they are not the same type. So the rule doesn't
apply here.

Zhaoxin

On Fri, Sep 2, 2016 at 7:02 AM, Nick Brook <nrbrook at gmail.com> wrote:

> Hi Jordan,
>
> Thanks for the advice.
>
> What if a subclass does implement hashValue differently? It seems you are
> saying a subclass should never override hashValue? Should Set not compare
> elements with == instead of hashValue?
>
> Thanks
> Nick
>
> M: +44 (0)7986 048 141
> W: http://nickbrook.me
>
> On 1 Sep 2016, at 23:55, Jordan Rose <jordan_rose at apple.com> wrote:
>
>
> 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/20160902/59b38ad7/attachment.html>


More information about the swift-users mailing list