Вот протокол, который я использую,
public protocol PValidationCondition: Equatable {
associatedtype T
func isValid(value: T) -> Bool
func errorMessage() -> String
}
Я использую эту модель:
struct PValidationElementWithConditions<T: PValidationCondition> {
let validationElement: PValidationElement
var conditions: [T] = []
}
Но я хотел бы сохранить несколько объектов в массиве следующим образом:
var validationElementsWithConditions: [String: PValidationElementWithConditions] = [:]
Но я получаю следующую ошибку:
"Cannot convert value of type '[String : PValidationElementWithConditions<_>]' to specified type '[String : PValidationElementWithConditions]'"
Поскольку он общий, вам нужно указать тип T в объявлении. Например:
var validationElementsWithConditions: [String: PValidationElementWithConditions<String>] = [:]
но я хочу сохранить в нем Int, String или любой другой объект, что мне делать в этом случае?
открытый класс ParakhValidator {открытый слабый делегат var: PValidatorDelegate? private var validationElementsWithConditions: [String: PValidationElementWithConditions <>] = [:] open static let shared = ParakhValidator () private init () {}}
это мой класс, который является одноэлементным
Это неверно
[String: PValidationElementWithConditions]
ты должен сделать
[String: PValidationElementWithConditions<Type>]
где Тип соответствует PValidationCondition
и Equatable
, из ошибки здесь ясно, что ему нужен параметр
PValidationElementWithConditions<_>
//
extension String : PValidationCondition {
public func isValid(value: String) -> Bool {
return true
}
public func errorMessage() -> String {
return ""
}
public typealias T = String
}
С
var validationElementsWithConditions: [String: PValidationElementWithConditions<String>] = [:]
Это не работает. Невозможно преобразовать значение типа «[AnyHashable: Any]» в указанный тип «[String: PValidationElementWithConditions <VComparisionCondition>]»
Это работает, но я хочу сохранить в нем Int, String или любой другой объект (тот же dict), что мне делать в этом случае?
вы можете рассматривать их все строки с интерполяцией "\ (12.5)"
Таким образом нельзя использовать протоколы + дженерики. Вы не можете смешивать Conditions<String>
с Conditions<Int>
. Вам нужно будет изменить дизайн, чтобы упростить ваши типы, или вам нужно будет создать упаковочную структуру PValidationElementWithConditions
, которая не раскрывает свой базовый тип (и, как правило, также не предоставляет к нему доступа). Но я рекомендую вам вернуться к проблеме, которую вы пытаетесь решить, и посмотреть, сможете ли вы создать ее с помощью более простых замыканий, а не протоколов. Протоколы в Swift очень хрупкие, PAT в 100 раз более хрупкие.
Однако проблема ключевого типа заключается в том, что если бы вы могли это сделать, как бы компилятор справился с validationElementsWithConditions.values.map { $0.conditions }
? Какой тип это вернет?
О, я вижу. Спасибо @RobNapier
необходимо указать тип PValidationElementWithConditions <YourType>