Validazione con i setter
Fa parte della sezione Programmazione orientata agli oggetti del percorso GDScript di Coddy. Lezione 27 di 65.
Un setter viene eseguito ogni volta che viene assegnato un valore alla sua proprietà, perciò è il punto in cui controllare il nuovo valore. Python genera un errore per un valore non valido. GDScript non ha eccezioni, quindi un setter fa invece una di queste cose: limita il valore all'intervallo consentito oppure mantiene il valore precedente e registra cosa è andato storto.
# 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) restituisce value riportato nell’intervallo da 0 a 100. Nel setter di nickname, return esce prima dell’assegnazione, quindi il vecchio nome rimane e last_error spiega perché:
# main.gd
var hero := Character.new()
hero.hp = 250
print(hero.hp) # 100
hero.nickname = "Al"
print(hero.nickname) # Player
print(hero.last_error) # Nome troppo corto
hero.nickname = "Alice"
print(hero.nickname) # AliceIl setter viene eseguito anche per le assegnazioni all'interno della classe, in _init() e in ogni metodo. Assegna gli argomenti del costruttore tramite la proprietà e verranno controllati anche loro:
func _init(start_hp: int) -> void:
hp = start_hp # esegue il setter: Character.new(500) inizia con 100All'interno del setter stesso, assegnare hp memorizza il valore senza richiamare il setter. L'unica assegnazione che ignora il setter è il valore iniziale nella dichiarazione (= 100), quindi quel valore deve essere valido di per sé.
Sfida
FacileAggiungi la convalida alla classe Thermostat in thermostat.gd con i setter:
target(inizia da20) accetta solo valori da10a30. Per qualsiasi altro valore mantiene il vecchio target e impostalast_errorsuTarget must be between 10 and 30.mode(inizia daoff) accetta soloheat,cooleoff. Per qualsiasi altro testo mantiene la vecchia modalità e impostalast_errorsuUnknown mode:seguito dal testo.- Un'assegnazione valida reimposta
last_errorsu una stringa vuota. _init(start_target)assegnastart_targetatarget, così il setter lo controlla.
Il codice fornito legge il target iniziale, poi il numero di comandi e infine un comando per riga (target 25 o mode cool). Dopo aver creato il termostato e dopo ogni comando, stampa Rejected: e l'errore quando last_error non è vuoto, quindi stampa lo stato. Con il valore iniziale 22 e i comandi target 35 e mode cool stampa:
Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode coolIl tuo codice va in thermostat.gd. main.gd contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
extends Node
func _ready():
# Codice di input/output fornito: lascialo così com'è
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])
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniIntroduzione alla programmazione orientata agli oggettiClassi e oggetti a confrontoLa parola chiave selfMetodiProprietàCostruttore (_init)Riepilogo - Calcolatrice semplice4Polimorfismo
Ripasso dell'override dei metodiDuck typingClassi e metodi astrattiProgettazione delle interfacceRiepilogo - Calcolatore di forme7Segnali
Che cos'è un segnale?Dichiarare ed emettereCollegarsi ai segnaliSegnali con argomentiRipasso - Sistema della salute10Pattern di progettazione, parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern Composite2Proprietà delle classi
Variabili di istanza e staticheFunzioni staticheSetter delle proprietàGetter delle proprietàPrivato per convenzioneRiepilogo - Gestore di conti bancari5Incapsulamento
Membri pubblici e privatiValidazione con i setterNascondimento delle informazioniProprietà di sola letturaRiepilogo - Sistema di gestione dei dati degli studenti8Concetti avanzati di OOP
Composizione vs ereditarietàClassi interneNodi come componentiRefCounted vs NodeEnum nelle classi11Progetto: Gestione della biblioteca
Panoramica del progettoClassi Libro e Utente3Ereditarietà
Ereditarietà di baseLa parola chiave superOverride dei metodiCatene di ereditarietàControlli di tipo con isRipasso - Gerarchia dei dipendenti6Metodi speciali
Introduzione ai metodi virtualiIl metodo _to_stringIteratori personalizzatiRiepilogo - Lista personalizzata9Modelli di progettazione, parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern ObserverPattern StrategyEsercitati da solo: Compilatore GDScript online