Различение унаследованных «ассоциированных типов» в протоколах Swift

#swift #generics #protocols #associated-types

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

Вопрос:

Я работаю с библиотекой, которая определяет два протокола, A и B , каждый со своим associatedtype T , вот так:

 protocol A {
    associatedtype T
}
protocol B {
    associatedtype T
}
  

Два протокола не связаны на T , и поэтому теоретически третий протокол может наследоваться от обоих A и B , typealias переводя каждый T в другой тип. К сожалению, я не могу заставить Swift различать эти два T типа. Я попробовал что-то вроде:

 protocol C: A, B {
    typealias A.T = String
    typealias B.T = String
}
  

но это не поддерживаемый синтаксис.
Есть ли способ обойти это?

Ответ №1:

Это обсуждалось в коллизии имен типа, ассоциированных с несколькими протоколами, на форуме Swift. Сяоди Ву пишет:

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

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

Таким образом, тип может соответствовать обоим A и B с идентичным связанным типом T , например

 struct Foo: A, B {
    typealias T = String
}
  

и протокол может наследоваться от обоих A и B и ограничиваться T идентичным типом:

 protocol C: A, B where T == String {
    
}
  

Соответствие обоим протоколам с различными связанными типами в настоящее время не поддерживается.