Протокол, соответствующий типу со связанным значением - PullRequest
0 голосов
/ 15 апреля 2020

У меня есть следующий фрагмент:

protocol MyProtocol: Identifiable where ID == UUID {
    var id: UUID { get }
}


var test: [MyProtocol] = []

Протокол 'MyProtocol' может использоваться только в качестве общего ограничения c, поскольку он имеет требования к Self или связанные с типами

Почему это не работает? Не должен ли where ID == UUID устранить неоднозначность, с которой связана ошибка? Я что-то здесь упускаю?

Я думаю, что этот вопрос похож на этот: Использование протоколов в качестве типов массивов и параметров функций в swift

Однако я бы хотел Предполагается, что добавление where ID == UUID должно решить проблему? Почему это не так?

Спасибо!

Редактировать

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

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

protocol MyProtocol: Identifiable where ID == UUID {
    var id: UUID { get }
}

struct A: MyProtocol { // First data model
    var id: UUID = UUID()
}

struct B: MyProtocol { // Second data model
    var id: UUID = UUID()
}

class DataManager: ObservableObject {
    var myData: [MyProtocol]
}

...

На самом деле мне не нужно объявлять Identifiable на MyProtocol, но я подумал, что это будет лучше и чище.

1 Ответ

3 голосов
/ 16 апреля 2020

Потому что это не текущая функция Swift. Когда есть связанный тип, всегда есть связанный тип. Он не исчезает только потому, что вы его сдерживаете. И как только у него есть связанный тип, он не конкретен.

Нет способа "наследовать" протоколы таким образом. То, что вы имеете в виду:

protocol MyProtocol {
    var id: UUID { get }
}

И затем вы можете прикрепить опознаваемый элемент к структурам, которые в нем нуждаются:

struct X: MyProtocol, Identifiable {
    var id: UUID
}

(обратите внимание, что пункт where не требуется.)

Сегодня не существует функции Swift, которая позволяет вам говорить «типы, которые соответствуют X, неявно соответствуют Y». На сегодняшний день также нет функции Swift, которая допускает массив «вещей, которые соответствуют Identifiable с ID == UUID». (Это называется обобщенным экзистенциалом, и в настоящее время он недоступен.)

Скорее всего, вам следует go вернуться к своему телефонному коду и выяснить, зачем вам это нужно. Если вы разместите код с итерацией test и, в частности, требует соответствия Identifiable, то мы сможем помочь вам найти проект, который не требует этого.

...