CustomStringConvertible
Часть раздела Объектно-ориентированное программирование путешествия по Swift на Coddy. Урок 37 из 57.
При выводе значения Swift по умолчанию показывает его тип и свойства, а для класса — только имя типа. Соответствие CustomStringConvertible и предоставление description позволяет управлять текстом:
struct Money {
let cents: Int
}
struct Price: CustomStringConvertible {
let cents: Int
var description: String { "$\(cents / 100).\(cents % 100)" }
}
print(Money(cents: 1250))
print(Price(cents: 1250))Результат:
Money(cents: 1250)
$12.50description используется print, интерполяцией строк и String(describing:), поэтому одно свойство управляет каждым местом, где отображается значение:
struct Point: CustomStringConvertible {
let x: Int, y: Int
var description: String { "(\(x), \(y))" }
}
let p = Point(x: 2, y: 5)
print("start at \(p)")
print([p, Point(x: 0, y: 0)])
print(String(describing: p).count)Результат:
start at (2, 5)
[(2, 5), (0, 0)]
6Больше всего это полезно для классов, поскольку при печати экземпляра класса в противном случае отображается только его имя типа:
class Account {
let owner: String
var balance: Int
init(owner: String, balance: Int) { self.owner = owner; self.balance = balance }
}
class NamedAccount: CustomStringConvertible {
let owner: String
var balance: Int
init(owner: String, balance: Int) { self.owner = owner; self.balance = balance }
var description: String { "\(owner): \(balance)" }
}
print(Account(owner: "Ada", balance: 5))
print(NamedAccount(owner: "Ada", balance: 5))Вывод:
main.Account
Ada: 5Делайте description коротким и понятным для людей. Он не предназначен для разбора и не должен изменять значение:
enum Status: CustomStringConvertible {
case active, suspended
var description: String {
switch self {
case .active: return "active"
case .suspended: return "suspended"
}
}
}Задание
ЛегкоСделайте структуру Fraction (числитель, знаменатель) соответствующей протоколу CustomStringConvertible. Её description отображает дробь в несократимом виде: 6/8 выводится как 3/4, 4/2 — как 2, 0/5 — как 0, а отрицательная дробь сохраняет знак перед числом (-1/2). Напишите вспомогательную функцию gcd(_:_:) для сокращения дроби.
Предоставленный код считывает дроби a/b, по одной в каждой строке, и выводит каждую из них с помощью print.
Ваш код должен находиться в файлах Fraction.swift и Functions.swift. В файле main.swift находится предоставленный код ввода/вывода, и его нельзя редактировать.
Попробуйте сами
// Предоставленный код ввода/вывода: оставьте его как есть
var input: [String] = []
while let line = readLine() { input.append(line) }
for line in input {
let p = line.split(separator: "/").map { Int($0)! }
print(Fraction(numerator: p[0], denominator: p[1]))
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовМетоды и selfИнициализаторыКлассы — это ссылкиПовторение — читательский билет4Инкапсуляция
Контроль доступаТолько чтение извнеЗащита состоянияИнициализаторы с возможностью сбояПовторение — банковский счёт7Полиморфизм и обобщения
ПолиморфизмПриведение типовОбобщённые функцииОбобщённые типыПовторение — калькулятор фигур10Паттерны проектирования. Часть 2
Паттерн делегированияПаттерн декораторПаттерн строительПаттерн состояния2Структуры и типы-значения
СтруктурыСемантика значенийИзменяющие методыСтруктура или классПовторение — элемент инвентаря5Наследование
ПодклассыПереопределение методовИнициализаторы и superfinal и иерархииПовторение — иерархия сотрудников8Стандартные протоколы
CustomStringConvertibleEquatableComparableHashableПовторение — пользовательская сортировка11Проект: Управление библиотекой
Книги и читателиВыдача книгПотренируйтесь самостоятельно: Песочница Swift