#swift #collections #type-alias #swift-keypath
#swift #Коллекции #псевдоним типа #swift-ключевой путь
Вопрос:
protocol PathCollection: Collection where Element == Target.Element, Index == Target.Index {
associatedtype Target: Collection
static var reference: KeyPath<Self, Target> { get }
}
extension PathCollection {
private var target: Target { self[keyPath: Self.reference] }
var startIndex: Index { target.startIndex }
var endIndex: Index { target.endIndex }
subscript(index: Index) -> Element {
get { target[index] }
}
func index(after i: Index) -> Index {
target.index(after: i)
}
}
Это довольно полезный протокол, который помогает нам сократить шаблонный код при создании пользовательских коллекций.
Предположим, что наша структура оборачивает словарь. И мы хотим, чтобы это была коллекция, подобная этому словарю.
Мы должны указать ключевой путь к свойству dictionary и применить его к протоколу. И это работает!
Пример использования и мой вопрос:
protocol Graph: PathCollection where Target == [String: Int] {
var storage: [String: Int] { get set }
}
extension Graph {
static var reference: KeyPath<Self, [String: Int]> { .storage }
}
struct UndirectedGraph: Graph {
typealias Element = Dictionary<String, Int>.Element // Why should we again declare this typealias!?
typealias Index = Dictionary<String, Int>.Index // Why should we again declare this typealias!?
var storage: [String: Int]
}
Это отлично работает. Но почему мы должны повторно объявлять типы элементов и индексов !? В самой первой строке кода этого поста мы явно определяем элемент и индекс:
protocol PathCollection: Collection where Element == Target.Element, Index == Target.Index {
и затем:
protocol Graph: PathCollection where Target == [String: Int] {
Если я удалю это повторное объявление, я получу ошибку компиляции, которую я не понимаю:
‘PathCollection’ требует типов ‘Slice’ и ‘Dictionary<String, Int>.Элемент’ (он же ‘(ключ: строка, значение: Int)’) эквивалентен
Комментарии:
1. Оказывается, вам не нужно переписывать оба псевдонима типа. Компилятору достаточно одного, чтобы разобраться. Но все же это странно.