У меня есть протокол:
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))
Но это, конечно, не работает, с ошибкой:
ошибка: протокол «Настраиваемый» может использоваться толькокак общее ограничение, потому что оно имеет Self или связанные требования к типу. var varSet: [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)
Или:
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!
}
Или
var brightness = ...
brightness.value = 1.5
set.append(.brightness)