Menu
CoddyTech

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

clampi(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)이므로, 해당 값은 그 자체로 유효해야 합니다.

challenge icon

챌린지

쉬움

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])
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 GDScript 컴파일러