Протокол с соответствующим типом в качестве обходных путей типа

#swift #protocols #associated-types

#swift #протоколы #связанные типы

Вопрос:

Я знаю, что в настоящее время невозможно использовать протоколы со связанными типами в качестве типов. Не могли бы вы помочь с обходными путями для этого случая:

 protocol ProvidesResult {
    associatedtype ResultType

    func provideResult(input: String) -> ResultType
}

class IntProvider: ProvidesResult {
    typealias ResultType = Int
    
    func provideResult(input: String) -> ResultType {
        //Logic
    }
}

var resultProviders: [String: ProvidesResult]
 

Мне нужен dict, где ключ — это строка, а значение — тип, соответствующий «ProvidesResult». Мне это нужно для инициирования новых экземпляров метода ResultProvider with provideResult .

Комментарии:

1. Вам нужно либо объявить свой словарь [String: Any], если вы хотите смешивать типы, либо объявить его типом ResultType , то есть [String: Int]

2. Вам нужен стиратель типа, например, AnyProviderResult

Ответ №1:

Один из подходов заключается в использовании стирания типов:

 struct AnyProvidesResult<T>: ProvidesResult {

    private _provideResult: (String) -> T

    init<PR>(_ pr: ProvidesResult) where PR: ProvidesResult {
        _provideResult = pr.provideResult
    }

    func provideResult(input: String) -> T {
        return _provideResult(input)
    }
}
 

Затем вы можете использовать приведенную выше конструкцию в своем словаре:

 var resultProviders: [String: AnyProvidesResult<TypeOfResult>]
 

Ограничение здесь заключается в том, что значения в словаре должны быть одного типа, поэтому вам нужно либо задать явный тип, либо использовать протокол общего знаменателя.