Menu
CoddyTech

사용자 정의 이터레이터

Coddy GDScript 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 65개 중 33번째.

Python은 __len__, __getitem__, __contains__, __iter__ 같은 매직 메서드를 사용해 클래스가 리스트처럼 동작하도록 합니다. Godot에는 이러한 작업 중 하나인 for 루프를 위한 가상 메서드만 있습니다. 다음 세 메서드로 for item in my_object:를 작동하게 할 수 있습니다.

  • _iter_init(iter)는 첫 번째 반복이 시작되기 전에 한 번 실행됩니다. 시작 위치를 설정하고 첫 번째 요소가 있으면 true를 반환합니다.
  • _iter_get(position)는 현재 위치의 요소를 반환하며, 루프 변수는 그 값을 받습니다.
  • _iter_next(iter)는 다음 반복부터 각 반복 전에 실행됩니다. 다음 위치로 이동하고 더 이상 요소가 없으면 false를 반환하여 루프를 종료합니다.
# team.gd
class_name Team
extends RefCounted

var _members: Array[String] = []

func add(member: String) -> void:
	_members.append(member)

func _iter_init(iter: Array) -> bool:
	iter[0] = 0
	return iter[0] < _members.size()

func _iter_next(iter: Array) -> bool:
	iter[0] += 1
	return iter[0] < _members.size()

func _iter_get(position):
	return _members[position]

iter는 Godot이 각 반복문마다 생성하는 슬롯 하나가 있는 배열입니다. iter[0]에는 해당 반복문의 위치가 저장되며, Godot은 그 값을 _iter_get()에 전달합니다. 이제 Team은 for 반복문에서 작동합니다:

var team := Team.new()
team.add("Ada")
team.add("Bo")
for member in team:
	print(member) # Ada, 그다음 Bo

위치는 iter[0]에 저장하고, _position과 같은 멤버 변수에는 저장하지 마세요. 각 루프는 자체 iter를 가지므로, 같은 팀을 순회하는 두 루프가 서로 중첩되어 있더라도 서로 방해하지 않습니다. 멤버 변수를 사용하면 내부 루프가 외부 루프의 위치를 이동시키게 됩니다.

다른 리스트 작업에는 가상 메서드가 없습니다. len(team)과 team[0]은 오류를 발생시킵니다. size(), get_at(index), has(member)처럼 Array의 메서드와 비슷한 이름으로 일반 메서드를 작성하세요. in으로 멤버십을 확인하지 마세요. "Ada" in team은 Team에 Ada라는 이름의 속성이나 메서드가 있는지 확인하므로, 결과는 false입니다.

challenge icon

챌린지

쉬움

bookshelf.gd에 Bookshelf 클래스를 작성하세요. 책 제목은 _titles에 저장하고, 책은 최대 _capacity권까지 보관합니다:

  • add(title)는 제목을 추가하고 true를 반환합니다. 책장이 가득 찼거나 이미 해당 제목이 있으면 추가하지 않고 false를 반환합니다.
  • size()는 책의 수를 반환하고, has(title)는 해당 제목이 책장에 있는지 반환합니다.
  • get_at(index)는 해당 인덱스의 제목을 반환하고, 인덱스가 책장의 범위를 벗어나면 빈 문자열을 반환합니다.
  • _iter_init(), _iter_next(), _iter_get()을 사용하면 for 루프에서 추가된 순서대로 제목을 순회할 수 있습니다.

제공된 코드는 보관 용량, 제목의 개수, 한 줄에 제목 하나씩을 읽고 추가할 수 없었던 제목을 출력합니다. 책의 수를 출력하고, 책장을 대상으로 하는 for 루프로 책 목록을 출력한 다음 제목을 하나 더 읽어 책장에 해당 제목이 있는지와 마지막 책을 출력합니다. 보관 용량이 3이고, 제목이 Dune, Emma, Dune, Ulysses, Hamlet이며 검색할 제목이 Emma일 때 출력 결과는 다음과 같습니다:

Could not add: Dune
Could not add: Hamlet
Books: 3
1. Dune
2. Emma
3. Ulysses
Has Emma: true
Last: Ulysses

코드는 bookshelf.gd에 작성하세요. main.gd에는 제공된 입력/출력 코드가 있으며 수정할 수 없습니다.

직접 해보기

extends Node

func _ready():
	# 제공된 입력/출력 코드: 그대로 유지하세요
	var shelf := Bookshelf.new(int(OS.read_string_from_stdin()))
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var title := OS.read_string_from_stdin()
		if not shelf.add(title):
			print("Could not add: " + title)
	print("Books: %d" % shelf.size())
	var number := 1
	for title in shelf:
		print("%d. %s" % [number, title])
		number += 1
	var query := OS.read_string_from_stdin()
	print("Has %s: %s" % [query, shelf.has(query)])
	print("Last: " + shelf.get_at(shelf.size() - 1))
quiz icon실력 점검

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

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

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