Проверка данных с помощью сеттеров
Часть раздела Объектно-ориентированное программирование путешествия по GDScript на Coddy. Урок 27 из 65.
Сеттер выполняется каждый раз, когда свойству присваивается значение, поэтому именно здесь нужно проверять новое значение. Python вызывает ошибку при недопустимом значении. В GDScript нет исключений, поэтому сеттер вместо этого делает одно из двух: ограничивает значение допустимым диапазоном или сохраняет прежнее значение и записывает, что пошло не так.
# character.gd
class_name Character
extends RefCounted
var last_error: String = ""
var hp: int = 100:
set(value):
hp = clampi(value, 0, 100)
var nickname: String = "Player":
set(value):
if value.length() < 3:
last_error = "Name too short"
return
last_error = ""
nickname = valueclampi(value, 0, 100) возвращает value, ограниченное диапазоном от 0 до 100. В сеттере nickname ключевое слово return завершает выполнение до присваивания, поэтому старое имя сохраняется, а last_error объясняет причину:
# main.gd
var hero := Character.new()
hero.hp = 250
print(hero.hp) # 100
hero.nickname = "Al"
print(hero.nickname) # Player
print(hero.last_error) # Name too short
hero.nickname = "Alice"
print(hero.nickname) # AliceСеттер также запускается при присваиваниях внутри класса, в _init() и в каждом методе. Передавай аргументы конструктора через свойство — они тоже будут проверены:
func _init(start_hp: int) -> void:
hp = start_hp # вызывает сеттер: Character.new(500) начинает со 100Внутри самого сеттера присваивание hp сохраняет значение, не вызывая сеттер повторно. Единственное присваивание, которое пропускает сеттер, — это начальное значение в объявлении (= 100), поэтому это значение должно быть допустимым само по себе.
Задание
ЛегкоДобавь проверку корректности в класс Thermostat в файле thermostat.gd с помощью сеттеров:
target(начальное значение —20) принимает только значения от10до30. Для любого другого значения он сохраняет прежнее значение и устанавливаетlast_errorвTarget must be between 10 and 30.mode(начальное значение —off) принимает толькоheat,coolиoff. Для любого другого текста он сохраняет прежнее значение и устанавливаетlast_errorвUnknown mode:, после которого добавляется этот текст.- При допустимом присваивании
last_errorснова устанавливается в пустую строку. _init(start_target)присваиваетstart_targetпеременнойtarget, поэтому для него выполняется проверка сеттером.
Предоставленный код считывает начальное значение целевой температуры, затем количество команд, а потом по одной команде в каждой строке (target 25 или mode cool). После создания термостата и после каждой команды он выводит Rejected: и сообщение об ошибке, если last_error не пуст, а затем — состояние. Для начального значения 22 и команд target 35 и mode cool вывод будет таким:
Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode coolТвой код нужно поместить в thermostat.gd. В main.gd находится предоставленный код ввода и вывода; его нельзя редактировать.
Попробуйте сами
extends Node
func _ready():
# Предоставленный код ввода-вывода: оставьте его без изменений
var thermostat := Thermostat.new(int(OS.read_string_from_stdin()))
report(thermostat)
var count := int(OS.read_string_from_stdin())
for i in count:
var parts := OS.read_string_from_stdin().split(" ")
if parts[0] == "target":
thermostat.target = int(parts[1])
else:
thermostat.mode = parts[1]
report(thermostat)
func report(thermostat: Thermostat) -> void:
if thermostat.last_error != "":
print("Rejected: " + thermostat.last_error)
print("Target %d, mode %s" % [thermostat.target, thermostat.mode])
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыВведение в ООПКлассы и объектыКлючевое слово selfМетодыСвойстваКонструктор (_init)Повторение: простой калькулятор4Полиморфизм
Переопределение методов: повторениеУтиная типизацияАбстрактные классы и методыПроектирование интерфейсовПовторение — калькулятор фигур7Сигналы
Что такое сигнал?Объявление и отправкаПодключение к сигналамСигналы с аргументамиПовторение — система здоровья10Паттерны проектирования. Часть 2
Паттерн «Команда»Паттерн «Адаптер»Паттерн «Декоратор»Паттерн «Шаблонный метод»Паттерн «Состояние»Паттерн «Компоновщик»2Свойства классов
Переменные экземпляра и классаСтатические функцииСеттеры свойствГеттеры свойствПриватность по соглашениюПовторение — менеджер банковского счёта5Инкапсуляция
Открытые и закрытые членыПроверка данных с помощью сеттеровСокрытие информацииСвойства только для чтенияПовторение — система учета студентов8Продвинутые концепции ООП
Композиция и наследованиеВнутренние классыУзлы как компонентыRefCounted и NodeПеречисления в классах11Проект: Управление библиотекой
Обзор проектаКлассы книг и пользователей3Наследование
Основы наследованияКлючевое слово superПереопределение методовЦепочки наследованияПроверка типов с помощью isПовторение — иерархия сотрудников6Специальные методы
Введение в виртуальные методыМетод _to_stringПользовательские итераторыПовторение: пользовательский список9Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн «Одиночка»Паттерн «Фабрика»Паттерн «Наблюдатель»Паттерн «Стратегия»Потренируйтесь самостоятельно: Онлайн-компилятор GDScript