Validação com setters
Parte da seção Programação orientada a objetos do Journey de GDScript da Coddy. Lição 27 de 65.
Um setter é executado toda vez que sua propriedade recebe um valor, o que faz dele o lugar certo para verificar o novo valor. Python gera um erro para um valor inválido. GDScript não tem exceções, então um setter faz uma destas coisas: limita o valor ao intervalo permitido ou mantém o valor antigo e registra o que deu errado.
# 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) retorna value ajustado ao intervalo de 0 a 100. No setter de nickname, return interrompe a execução antes da atribuição, então o nome antigo permanece e last_error explica o motivo:
# 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) # AliceO setter também é executado para atribuições dentro da classe, em _init() e em todos os métodos. Atribua os argumentos do construtor por meio da propriedade e eles também serão verificados:
func _init(start_hp: int) -> void:
hp = start_hp # executa o setter: Character.new(500) começa com 100Dentro do próprio setter, atribuir hp armazena o valor sem chamar o setter novamente. A única atribuição que não passa pelo setter é o valor inicial na declaração (= 100), então esse valor precisa ser válido por si só.
Desafio
FácilAdicione validação à classe Thermostat em thermostat.gd com setters:
target(começa em20) aceita apenas valores de10a30. Para qualquer outro valor, mantém o target antigo e definelast_errorcomoTarget must be between 10 and 30.mode(começa emoff) aceita apenasheat,cooleoff. Para qualquer outro texto, mantém o modo antigo e definelast_errorcomoUnknown mode:seguido do texto.- Uma atribuição válida redefine
last_errorpara uma string vazia. _init(start_target)atribuistart_targetatarget, para que o setter faça a verificação.
O código fornecido lê o target inicial, depois o número de comandos e, em seguida, um comando por linha (target 25 ou mode cool). Depois de criar o termostato e após cada comando, ele imprime Rejected: e o erro quando last_error não está vazio, e então o estado. Para o início 22 e os comandos target 35 e mode cool, ele imprime:
Target 22, mode off
Rejected: Target must be between 10 and 30
Target 22, mode off
Target 22, mode coolSeu código deve ficar em thermostat.gd. main.gd contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
extends Node
func _ready():
# Código de entrada/saída fornecido: mantenha-o como está
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])
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação orientada a objetos
1Fundamentos da POO
Arquivos externosIntrodução à POOClasses vs. objetosA palavra-chave selfMétodosPropriedadesConstrutor (_init)Revisão - Calculadora simples4Polimorfismo
Revisitando a Sobrescrita de MétodosDuck TypingClasses e Métodos AbstratosDesign de InterfacesRevisão - Calculadora de Formas7Sinais
O que é um sinal?Declarando e emitindoConectando-se a sinaisSinais com argumentosRevisão - Sistema de saúde10Padrões de Projeto Parte 2
Padrão CommandPadrão AdapterPadrão DecoratorPadrão Template MethodPadrão StatePadrão Composite2Propriedades de Classe
Variáveis de Instância vs. EstáticasFunções EstáticasMétodos Setters de PropriedadeMétodos Getters de PropriedadePrivado por ConvençãoRecapitulando: Gerenciador de Conta Bancária5Encapsulamento
Membros públicos e privadosValidação com settersOcultação de informaçõesPropriedades somente para leituraRevisão - Sistema de registros de alunos8Conceitos Avançados de POO
Composição vs. HerançaClasses InternasNós como ComponentesRefCounted vs. NodeEnums em Classes3Herança
Herança básicaA palavra-chave superSobrescrita de métodosCadeias de herançaVerificações de tipo com isRevisão - Hierarquia de funcionários6Métodos especiais
Introdução aos métodos virtuaisO método _to_stringIteradores personalizadosRevisão - Lista personalizada9Padrões de Projeto Parte 1
Introdução aos Padrões de ProjetoPadrão SingletonPadrão FactoryPadrão ObserverPadrão StrategyPratique por conta própria: Compilador de GDScript online