I've got a protocol:
protocol Adjustable: Equatable {
associatedtype T
var id: String { get set }
var value: T { get set }
init(id: String, value: T)
}
And a struct that conforms to it:
struct Adjustment: Adjustable {
static func == (lhs: Adjustment, rhs: Adjustment) -> Bool {
return lhs.id == rhs.id
}
typealias T = CGFloat
var id: String
var value: T
}
And I'm building a wrapper class that behaves like a Set to handle an ordered list of these properties:
struct AdjustmentSet {
var adjustmentSet: [Adjustable] = []
func contains<T: Adjustable>(_ item: T) -> Bool {
return adjustmentSet.filter({ $0.id == item.id }).first != nil
}
}
let brightness = Adjustment(id: "Brightness", value: 0)
let set = AdjustmentSet()
print(set.contains(brightness))
But that of course doesn't work, erroring with:
error: protocol 'Adjustable' can only be used as a generic constraint because it has Self or associated type requirements var adjustmentSet: [Adjustable] = []
Looking around, I thought at first this was because the protocol doesn't conform to Equatable, but then I added it, and it still doesn't work (or I did it wrong).
Moreover, I would like to be able to use a generic here, so that I can do something like:
struct Adjustment<T>: Adjustable {
static func == (lhs: Adjustment, rhs: Adjustment) -> Bool {
return lhs.id == rhs.id
}
var id: String
var value: T
}
let brightness = Adjustment<CGFloat>(id: "Brightness", value: 0)
Or:
struct FloatAdjustment: Adjustable {
static func == (lhs: Adjustment, rhs: Adjustment) -> Bool {
return lhs.id == rhs.id
}
typealias T = CGFloat
var id: String
var value: T
}
let brightness = FloatAdjustment(id: "Brightness", value: 0)
And still be able to store an array of [Adjustable] types, so that eventually I can do:
var set = AdjustmentSet()
if set.contains(.brightness) {
// Do something!
}
Or
var brightness = ...
brightness.value = 1.5
set.append(.brightness)