Hi Zhao

Thanks for your response.

I understand your point, but when using third party classes I don’t know if the 
hash values are comparable, but for example I may want to have a set of ‘data' 
(NSData) and a subset of ‘mutable data' (NSMutableData), which point to the 
same objects. As a user of swift I would expect to be able to subtract 
Set<NSMutableData> from Set<NSData>.

Your last example perhaps works in Swift 3, so this may be fixed now, but in 
Swift 2 you get the error

Cannot invoke 'subtract' with an argument list of type '(Set<Bar>)’

Perhaps Swift 3 supports it with some additional safety around hashValue 
overriding or something.

Thanks

Nick

> On 1 Sep 2016, at 04:00, Zhao Xin <owe...@gmail.com> wrote:
> 
> I don't see the point. For example if an element in Set<B> and another 
> element in Set<A> are with a same hash value. Neither of the elements should 
> be subtracted. As they are in different types. And hash values between 
> different types are not guaranteed to be comparable. 
> 
> import Foundation
> 
> class Foo:Hashable {
>     var value: Int
>     
>     public var hashValue: Int {
>         return value
>     }
>     
>     public static func ==(lhs: Foo, rhs: Foo) -> Bool {
>         return lhs.value == rhs.value
>     }
>     
>     required init(_ value:Int) {
>         self.value = value
>     }
> }
> 
> class Bar:Foo {
>     override public var hashValue: Int {
>         return value * 10
>     }
> }
> 
> let foo = Foo(10)
> let bar = Bar(10)
> 
> print(foo.hashValue) // 10
> print(bar.hashValue) // 100
> print((bar as Foo).hashValue) // 100 instead of 10
> 
> print(foo == bar) // true
> print(foo.hashValue == bar.hashValue) // false
> 
> As you can see in the above code, although `foo == bar` is true, 
> `foo.hashValue == bar.hashValue` is not guaranteed to be true. As far as I 
> know, Set<T> uses hash values instead of equations to compare the elements. 
> So the results of a super class and its sub class are not guaranteed. Also, 
> as `(bar as Foo).hashValue` is always the result of its own class, you can't 
> get the results you want through casting.
> 
> 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)
> fooSet.forEach { print("\(type(of:$0)), value:\($0.value)") }
> /*
>  Foo, value:10
>  Foo, value:9
>  Foo, value:8 // Here is a mystery, Foo(7) is unreasonably missing.
> */
> 
> However, if you can guarantee the hash values are comparable, you still can 
> get the results you want.
> 
> class Foo:Hashable {
>     var value: Int
>     
>     public var hashValue: Int {
>         return value
>     }
>     
>     public static func ==(lhs: Foo, rhs: Foo) -> Bool {
>         return lhs.value == rhs.value
>     }
>     
>     required init(_ value:Int) {
>         self.value = value
>     }
> }
> 
> class Bar:Foo {
>     var name = "bar"
> }
> 
> 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)
> fooSet.forEach { print("\(type(of:$0)), value:\($0.value)") }
> /*
>  Foo, value:10
>  Foo, value:9
> */
> 
> 
> Zhaoxin
> 
> On Thu, Sep 1, 2016 at 8:31 AM, Nick Brook via swift-users 
> <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:
> I have a set, Set<A> and a subset of that, Set<B>, where B: A. I want to 
> subtract Set<B> from Set<A>, but the subtract function signature specifies 
> that the set elements must be the same type (S.Generator.Element == Element). 
> I guess this is because Element is not required to be a class, simply 
> hashable, therefore inheritance is not guaranteed? Is there any way this 
> could be implemented in Set, in an extension, or what would be the most 
> efficient way to perform that operation?
> 
> Thanks
> 
> Nick
> 
> _______________________________________________
> swift-users mailing list
> swift-users@swift.org <mailto:swift-users@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-users 
> <https://lists.swift.org/mailman/listinfo/swift-users>
> 
> 

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to