Menu
CoddyTech

Walidacja za pomocą setterów

Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 27 z 65.

Setter jest uruchamiany za każdym razem, gdy przypisywana jest wartość jego właściwości, dlatego to właśnie w nim należy sprawdzać nową wartość. Python zgłasza błąd w przypadku nieprawidłowej wartości. GDScript nie obsługuje wyjątków, więc setter robi zamiast tego jedną z dwóch rzeczy: ogranicza wartość do zakresu albo zachowuje starą wartość i zapisuje, co poszło nie tak.

# 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 = value

clampi(value, 0, 100) zwraca value ograniczone do zakresu od 0 do 100. W setterze nickname instrukcja return kończy działanie przed przypisaniem, więc poprzednia nazwa pozostaje, a last_error wyjaśnia dlaczego:

# 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

Setter działa również przy przypisaniach wewnątrz klasy, w _init() i w każdej metodzie. Przypisz argumenty konstruktora za pomocą właściwości, a one również zostaną sprawdzone:

func _init(start_hp: int) -> void:
	hp = start_hp # wywołuje setter: Character.new(500) zaczyna z wartością 100

W samym setterze przypisanie hp zapisuje wartość bez ponownego wywoływania settera. Jedynym przypisaniem, które pomija setter, jest wartość początkowa w deklaracji (= 100), więc ta wartość musi być poprawna sama w sobie.

challenge icon

Wyzwanie

Łatwy

Dodaj walidację do klasy Thermostat w pliku thermostat.gd za pomocą setterów:

  • target (początkowo 20) przyjmuje tylko wartości od 10 do 30. Dla każdej innej wartości zachowuje poprzednią wartość docelową i ustawia last_error na Target must be between 10 and 30.
  • mode (początkowo off) przyjmuje tylko wartości heat, cool i off. Dla każdego innego tekstu zachowuje poprzedni tryb i ustawia last_error na Unknown mode: , po którym następuje ten tekst.
  • Poprawne przypisanie ustawia last_error z powrotem na pusty ciąg znaków.
  • _init(start_target) przypisuje start_target do target, dzięki czemu wartość jest sprawdzana przez setter.

Dostarczony kod odczytuje początkową wartość docelową, następnie liczbę poleceń, a potem jedno polecenie w każdym wierszu (target 25 lub mode cool). Po utworzeniu termostatu i po każdym poleceniu wypisuje Rejected: i błąd, gdy last_error nie jest pusty, a następnie stan. Dla początkowej wartości 22 i poleceń target 35 oraz mode cool wypisuje:

Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode cool

Twój kod umieść w pliku thermostat.gd. Plik main.gd zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

extends Node

func _ready():
	# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
	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])
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator GDScript online