Ответ
Да, можно. Это мощная техника для добавления требований протокола и реализации по умолчанию через условные расширения.
1. Добавление соответствия протоколу с реализацией по умолчанию
protocol Displayable {
var displayName: String { get }
}
protocol Identifiable {
var id: UUID { get }
}
// Расширяем Identifiable, добавляя соответствие Displayable
// только для типов, которые уже соответствуют Identifiable
extension Identifiable {
var displayName: String {
return "ID: (id.uuidString.prefix(8))"
}
}
// Теперь любой тип, соответствующий Identifiable,
// автоматически получает реализацию Displayable
struct User: Identifiable {
let id = UUID()
// displayName доступен автоматически
}
let user = User()
print(user.displayName) // "ID: A1B2C3D4"
2. Условные расширения с where-ограничениями
protocol Savable {
func save()
}
// Добавляем соответствие Savable только для Collection,
// элементы которой соответствуют Codable
extension Collection where Element: Codable {
func save() {
let encoder = JSONEncoder()
if let data = try? encoder.encode(self) {
// Сохранение данных
UserDefaults.standard.set(data, forKey: "collection")
}
}
}
// Теперь массив Codable объектов получает метод save()
struct Item: Codable {}
let items: [Item] = [Item(), Item()]
items.save() // Работает!
Ключевые преимущества:
- Повышение переиспользуемости кода
- Избегание дублирования реализации
- Точечное добавление функциональности только нужным типам
- Поддержка протокол-ориентированного дизайна