У меня есть протокол:
protocol Adjustable: Equatable {
associatedtype T
var id: String { get set }
var value: T { get set }
init(id: String, value: T)
}
И структура, которая ему соответствует:
struct Adjustment: Adjustable {
static func == (lhs: Adjustment, rhs: Adjustment) -> Bool {
return lhs.id == rhs.id
}
typealias T = CGFloat
var id: String
var value: T
}
И я создаю класс-оболочку, который ведет себя как Set
для обработки упорядоченного списка этих свойств:
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))
Но это, конечно, не работает, ошибка с:
ошибка: протокол "Adjustable" может использоваться только как общее ограничение, потому что он имеет требования типа Self или связанный с ним var adjustSet: [Adjustable] = []
Оглядываясь вокруг, я сначала подумал, что это потому, что протокол не соответствует Equatable
, но потом я добавил его, но он по-прежнему не работает (или я сделал это неправильно).
Более того, я хотел бы иметь возможность использовать здесь общий тип, чтобы я мог делать что-то вроде:
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)
И все же у меня будет возможность хранить массив из [Adjustable]
типов, чтобы в конечном итоге я мог:
var set = AdjustmentSet()
if set.contains(.brightness) {
// Do something!
}
Or
var brightness = ...
brightness.value = 1.5
set.append(.brightness)