Семантика значений
Часть раздела Объектно-ориентированное программирование путешествия по Swift на Coddy. Урок 8 из 57.
Структуры являются типами значений: присваивание структуры другой переменной копирует её. Изменение копии не затрагивает оригинал, в отличие от класса:
struct Point {
var x: Int
}
var a = Point(x: 1)
var b = a
b.x = 99
print(a.x)
print(b.x)Вывод:
1
99То же сравнение с классом показывает разницу: обе переменные ссылаются на один объект.
class PointRef {
var x: Int
init(x: Int) { self.x = x }
}
let a = PointRef(x: 1)
let b = a
b.x = 99
print(a.x)Результат:
99Передача структуры в функцию также передаёт её копию. Параметр является константой, поэтому, чтобы вернуть изменённую версию, функция создаёт локальную копию и возвращает её:
struct Point {
var x: Int
}
func shifted(_ p: Point, by dx: Int) -> Point {
var copy = p
copy.x += dx
return copy
}
let start = Point(x: 1)
let moved = shifted(start, by: 4)
print(start.x)
print(moved.x)Вывод:
1
5Массивы структур содержат независимые значения. Изменение элемента по его индексу изменяет только этот элемент, а копирование массива копирует каждое значение:
struct Score {
var points: Int
}
var round1 = [Score(points: 1), Score(points: 2)]
var round2 = round1
round2[0].points = 50
print(round1[0].points)
print(round2[0].points)Вывод:
1
50Задание
ЛегкоРеализуй tryDiscount(_:percent:). Она получает структуру Price и возвращает копию со скидкой: количество центов уменьшается на указанный процент с округлением вниз. Предоставленный код выводит исходную цену и цену со скидкой, поэтому исходная цена должна остаться неизменной.
Предоставленный код считывает цену в центах и один процент в каждой строке и для каждой пары выводит was 1000, now 900.
Твой код должен находиться в Price.swift и Functions.swift. В main.swift находится предоставленный код ввода/вывода, и его нельзя изменять.
Попробуйте сами
// Предоставленный код ввода/вывода: оставьте его как есть
var input: [String] = []
while let line = readLine() { input.append(line) }
let original = Price(cents: Int(input[0])!)
for line in input.dropFirst() {
let cheaper = tryDiscount(original, percent: Int(line)!)
print("was \(original.cents), now \(cheaper.cents)")
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Классы и объекты
Работа с файламиОпределение классовМетоды и selfИнициализаторыКлассы — это ссылкиПовторение — читательский билет4Инкапсуляция
Контроль доступаТолько чтение извнеЗащита состоянияИнициализаторы с возможностью сбояПовторение — банковский счёт7Полиморфизм и обобщения
ПолиморфизмПриведение типовОбобщённые функцииОбобщённые типыПовторение — калькулятор фигур10Паттерны проектирования. Часть 2
Паттерн делегированияПаттерн декораторПаттерн строительПаттерн состояния2Структуры и типы-значения
СтруктурыСемантика значенийИзменяющие методыСтруктура или классПовторение — элемент инвентаря5Наследование
ПодклассыПереопределение методовИнициализаторы и superfinal и иерархииПовторение — иерархия сотрудников8Стандартные протоколы
CustomStringConvertibleEquatableComparableHashableПовторение — пользовательская сортировка11Проект: Управление библиотекой
Книги и читателиВыдача книгПотренируйтесь самостоятельно: Песочница Swift