В коде допущена ошибка. Объясните её причину и покажите корректное место для объявления наследования протоколов.
protocol Readable { }
protocol Storable { }
extension Readable: Storable { }
Ошибка возникает потому, что расширение протокола не может объявить его наследование от другого протокола. Связь Readable: Storable должна быть указана в исходном объявлении протокола: protocol Readable: Storable { }.
Расширение может добавлять методы, свойства, реализации требований и ограниченные реализации, но не изменяет иерархию протоколов.
Extensions отделяют основное описание типа или протокола от дополнительных возможностей. Это позволяет организовать код, добавить реализацию требований и адаптировать тип к протоколу без изменения его исходного тела.
Наследование протоколов относится не к реализации, а к модели типов. Компилятор должен знать эту связь при проверке соответствий, построении ограничений и формировании набора требований протокола, поэтому она задаётся в объявлении самого протокола.
Если попытаться добавить наследование через extension, компилятор отвергнет конструкцию с наследуемым протоколом. Нельзя таким способом задним числом сделать так, чтобы все типы, соответствующие Readable, автоматически соответствовали Storable.
Это важно для generic-кода. Ограничение T: Readable включает только требования Readable; оно не должно неожиданно приобретать требования Storable из расширения, подключённого в другом файле или модуле.
Наследование объявляется так:
Теперь Readable включает требования Storable, поэтому соответствие Document протоколу Readable требует реализовать оба метода. Generic-параметр с ограничением T: Readable также может использовать read() и save().
Расширение может предоставить реализацию уже объявленных требований:
Но оно не может превратить Readable в наследника Storable. Это принципиальное различие между добавлением реализации и изменением отношений типов.
Если требуется, чтобы только часть типов получила дополнительное поведение, следует использовать отдельное соответствие конкретных типов или условное соответствие generic-типа, а не пытаться изменить наследование протокола через расширение.
В библиотеке есть протокол Readable, используемый множеством клиентов. Позже появляется требование сохранять только документы нового формата. Разработчик пытается добавить Storable через расширение Readable, чтобы автоматически распространить новое требование на все существующие типы.
Вариант с protocol Readable: Storable технически корректен, но нарушает совместимость: все прежние соответствия Readable должны теперь удовлетворять Storable. Такой подход оправдан только при изменении контракта всей библиотеки.
Вариант с расширением Readable не решает задачу и не компилируется. Практичнее объявить отдельный протокол ReadableStorable: Readable, Storable или добавить Storable только нужным типам. Это сохраняет старый контракт и явно показывает, какие документы поддерживают сохранение.
Вопрос: Если Readable наследуется от Storable, обязан ли тип, соответствующий Readable, явно указывать оба соответствия?
Ответ: Нет. Достаточно указать соответствие Readable. Поскольку Readable включает Storable, компилятор проверит требования обоих протоколов в рамках одного соответствия. Отдельная запись Storable обычно избыточна.
Вопрос: Можно ли через расширение протокола добавить ему новые обязательные требования?
Ответ: Нет. Расширение может содержать реализации, вычисляемые свойства и дополнительные методы, но добавленные там объявления не становятся требованиями протокола для соответствующих типов. Обязательное требование должно находиться в объявлении протокола, иначе generic-код и проверка соответствий не смогут на него опираться.
Вопрос: Что изменится, если вместо наследования объявить extension Document: Storable?
Ответ: Это может быть корректным способом добавить конкретному типу соответствие Storable, если тип доступен для такого расширения и все требования реализованы. Но это не изменит протокол Readable: другие типы, соответствующие Readable, не станут Storable автоматически. Поэтому соответствие конкретного типа и наследование протоколов решают разные задачи.