I'm building an document-based app, and I'm having a problem regarding to Set.
What I hope to achieve is to have a Set of unique objects by their references. For example, I might put in two rectangles with the same height and width (which makes them equal, but they are still different instances). Currently, I have two solutions:
Option 1:
Inherit from NSObject
class Rectangle: NSObject {
var height, width: Int
func isEqualByValue(_ other: Rectangle) -> Bool {
return height == other.height && width == other.width
}
}
Set<Rectangle> meets my requirements, but it drags a lot of baggage from Objective-C, also makes comparing by value ugly.
Option 2:
Wrap them
struct RectangleReference: Hashable {
let value: Rectangle
var hashValue: Int {
return unsafeAddress(of: value).hashValue // This might be removed in Swift 3 (SR-1957)
}
}
func ==(lhs: RectangleReference, rhs: RectangleReference) -> Bool {
return lhs.value === rhs.value
}
Set<RectangleReference> works fine, but it has unsafeAddress(of:) which is unsafe and might be removed in Swift 3.
What I'd like to use is a ReferenceSet<Element: AnyObject> which compares objects by their references. Any reference typed instances can be put in it without confirming to Hashable protocol. ReferenceDictionary<Key: AnyObject, Value> is also welcomed.
public final class ReferenceEqualityBox<Wrapped : Equatable> : Hashable {
public var value: Wrapped
public init(_ value: Wrapped) {
self.value = value
}
public var hashValue: Int {
return ObjectIdentifier(self).hashValue
}
}
public func == <Wrapped> (
lhs: ReferenceEqualityBox<Wrapped>,
rhs: ReferenceEqualityBox<Wrapped>
) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
Dmitri
···
On Sun, Jul 17, 2016 at 2:00 AM, 张国晔 via swift-evolution <swift-evolution@swift.org> wrote:
I'm building an document-based app, and I'm having a problem regarding to Set.
What I hope to achieve is to have a Set of unique objects by their references.
What I hope to achieve is to have a Set of unique objects by their references. For example, I might put in two rectangles with the same height and width (which makes them equal, but they are still different instances).
I guess this is not the best place for such problems, but did you already look at ObjectIdentifier?
What I hope to achieve is to have a Set of unique objects by their references. For example, I might put in two rectangles with the same height and width (which makes them equal, but they are still different instances).
I guess this is not the best place for such problems, but did you already look at ObjectIdentifier?
Tino
The problem is the motivation for my proposal of adding ReferenceSet<Element: AnyObject> and ReferenceDictionary<Key: AnyObject, Value> to stdlib.
The original object cannot be retrieved from ObjectIdentifier, which makes it unsuitable for my use-case.
I'm building an document-based app, and I'm having a problem regarding to Set.
What I hope to achieve is to have a Set of unique objects by their references.
Try this:
public final class ReferenceEqualityBox<Wrapped : Equatable> : Hashable {
public var value: Wrapped
public init(_ value: Wrapped) {
self.value = value
}
public var hashValue: Int {
return ObjectIdentifier(self).hashValue
}
}
public func == <Wrapped> (
lhs: ReferenceEqualityBox<Wrapped>,
rhs: ReferenceEqualityBox<Wrapped>
) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}