Общая проблема при создании массива в swift

Вот протокол, который я использую,

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]'"

необходимо указать тип PValidationElementWithConditions <YourType>

vivekDas 10.08.2018 15:41
2
1
85
2

Ответы 2

Поскольку он общий, вам нужно указать тип T в объявлении. Например:

var validationElementsWithConditions: [String: PValidationElementWithConditions<String>] = [:]

но я хочу сохранить в нем Int, String или любой другой объект, что мне делать в этом случае?

Teenenggr 10.08.2018 15:44

открытый класс ParakhValidator {открытый слабый делегат var: PValidatorDelegate? private var validationElementsWithConditions: [String: PValidationElementWithConditions <>] = [:] open static let shared = ParakhValidator () private init () {}}

Teenenggr 10.08.2018 15:46

это мой класс, который является одноэлементным

Teenenggr 10.08.2018 15:47

Это неверно

[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>]»

Teenenggr 10.08.2018 16:02

Это работает, но я хочу сохранить в нем Int, String или любой другой объект (тот же dict), что мне делать в этом случае?

Teenenggr 10.08.2018 16:20

вы можете рассматривать их все строки с интерполяцией "\ (12.5)"

Sh_Khan 10.08.2018 17:18

Таким образом нельзя использовать протоколы + дженерики. Вы не можете смешивать Conditions<String> с Conditions<Int>. Вам нужно будет изменить дизайн, чтобы упростить ваши типы, или вам нужно будет создать упаковочную структуру PValidationElementWithConditions, которая не раскрывает свой базовый тип (и, как правило, также не предоставляет к нему доступа). Но я рекомендую вам вернуться к проблеме, которую вы пытаетесь решить, и посмотреть, сможете ли вы создать ее с помощью более простых замыканий, а не протоколов. Протоколы в Swift очень хрупкие, PAT в 100 раз более хрупкие.

Rob Napier 10.08.2018 17:31

Однако проблема ключевого типа заключается в том, что если бы вы могли это сделать, как бы компилятор справился с validationElementsWithConditions.values.map { $0.conditions }? Какой тип это вернет?

Rob Napier 10.08.2018 17:32

О, я вижу. Спасибо @RobNapier

Teenenggr 10.08.2018 18:37

Другие вопросы по теме