Setter를 통한 유효성 검사
Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 27번째.
세터는 해당 속성에 값이 할당될 때마다 실행되므로 새 값을 확인하기에 적합한 곳입니다. 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) # 플레이어
print(hero.last_error) # 이름이 너무 짧음
hero.nickname = "Alice"
print(hero.nickname) # Alice세터는 클래스 내부의 대입에도 실행됩니다. _init()에서뿐 아니라 모든 메서드에서도 실행됩니다. 생성자의 인수를 속성을 통해 대입하면 해당 인수도 검사됩니다:
func _init(start_hp: int) -> void:
hp = start_hp # setter를 실행합니다: Character.new(500)은 100으로 시작합니다setter 자체에서 hp를 할당하면 setter를 다시 호출하지 않고 값을 저장합니다. setter를 건너뛰는 유일한 할당은 선언의 초기값(= 100)이므로, 해당 값은 그 자체로 유효해야 합니다.
챌린지
쉬움thermostat.gd의 Thermostat 클래스에 세터를 사용해 유효성 검사를 추가하세요.
target(초깃값은20)에는10부터30까지의 값만 허용됩니다. 그 외의 값이 지정되면 기존 target을 유지하고last_error를Target must be between 10 and 30으로 설정합니다.mode(초깃값은off)에는heat,cool,off만 허용됩니다. 그 외의 텍스트가 지정되면 기존 mode를 유지하고last_error를Unknown mode:뒤에 해당 텍스트가 오도록 설정합니다.- 유효한 값을 할당하면
last_error를 빈 문자열로 되돌립니다. _init(start_target)은start_target을target에 할당하므로 세터가 값을 검사합니다.
제공된 코드는 시작 target을 읽고, 이어서 명령 개수를 읽은 다음, 한 줄에 하나씩 명령을 읽습니다(target 25 또는 mode cool). 서모스탯을 생성한 후와 각 명령을 실행한 후에 last_error가 비어 있지 않으면 Rejected: 와 오류를 출력한 다음 상태를 출력합니다. 시작값이 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])
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 GDScript 컴파일러