问题
I need container for Any Equatable
items in NOT Generic
class (for example UI classes initial from storyboard). I need like this
var items: [Equatable]?
but it don't work, Equatable
need Generic. the problem that there is no exist common Equatable
class.
Ok - Go to generic! But if I do this
class Item<Value: Equatable>: Equatable {
var value: Value
init(_ value: Value) {
self.value = value
}
//Equatable
public static func ==(lhs: Item, rhs: Item) -> Bool {
return (lhs.value == rhs.value)
}
}
then I will be forced to specify the type in my nonGeneric-UI class. Like this
var items: [Item<WhatShouldBeHere?>]?
but again we come to the problem that there is no exist common Equatable
class
Any solutions for container for All Equatable?
回答1:
In lieu of existential types, you need to use a type eraser:
public struct AnyEquatable: Equatable {
public let value: Any
private let equals: (Any) -> Bool
public init<E: Equatable>(_ value: E) {
self.value = value
self.equals = { ($0 as? E) == value }
}
public static func == (lhs: AnyEquatable, rhs: AnyEquatable) -> Bool {
return lhs.equals(rhs.value) || rhs.equals(lhs.value)
}
}
example usage:
let items = [
AnyEquatable(1),
AnyEquatable(1.23),
AnyEquatable(true),
AnyEquatable("some string")
]
let desired = "some string"
let desiredAsAnyEquatable = AnyEquatable(desired)
let desiredDescription = String(reflecting: desired)
for item in items {
let itemDescription = String(reflecting: item.value)
let isEqualToDesired = item == desiredAsAnyEquatable
print("\(itemDescription) is \(isEqualToDesired ? "": "not ")equal to \(desiredDescription)")
}
Example output:
1 is not equal to "some string"
1.23 is not equal to "some string"
true is not equal to "some string"
"some string" is equal to "some string"
来源:https://stackoverflow.com/questions/46288560/common-equatable-class-on-swift