Для чего используется протокол CustomStringConvertible в Swift?

«Для чего используется протокол CustomStringConvertible в Swift?» — вопрос из категории Swift Core, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

CustomStringConvertible — это протокол в Swift, который позволяет предоставить пользовательское текстовое представление для экземпляра вашего типа. Это представление используется функциями отладки и логирования, такими как print() и String(describing:).

Как это работает: Тип, соответствующий протоколу, должен реализовать вычисляемое свойство только для чтения description типа String.

Пример реализации:

struct Coordinate: CustomStringConvertible {
    let latitude: Double
    let longitude: Double

    // Пользовательское текстовое представление.
    var description: String {
        return String(format: "(%.4f, %.4f)", latitude, longitude)
    }
}

let london = Coordinate(latitude: 51.5074, longitude: -0.1278)
print(london) // Выведет: "(51.5074, -0.1278)"
print("Location: (london)") // Location: (51.5074, -0.1278)
let stringRepresentation = String(describing: london) // "(51.5074, -0.1278)"

Без соответствия CustomStringConvertible print(london) вывел бы стандартное описание структуры (например, Coordinate(latitude: 51.5074, longitude: -0.1278)).

Отличие от CustomDebugStringConvertible:

  • CustomStringConvertible (description) — для пользовательского и публичного представления объекта. Это то, что вы хотите показать в логах или UI.
  • CustomDebugStringConvertible (debugDescription) — для отладочного представления, используется дебаггером (например, в po команде LLDB) и функцией debugPrint(). Обычно содержит более детальную внутреннюю информацию.
struct Coordinate: CustomStringConvertible, CustomDebugStringConvertible {
    let latitude: Double
    let longitude: Double

    var description: String { "(lat: (latitude), lon: (longitude))" }
    var debugDescription: String { "Coordinate(latitude: (latitude), longitude: (longitude))" }
}

let point = Coordinate(latitude: 10.0, longitude: 20.0)
print(point) // (lat: 10.0, lon: 20.0)
debugPrint(point) // Coordinate(latitude: 10.0, longitude: 20.0)

Использование этих протоколов делает отладку и логирование более информативными и читаемыми.