Menu
CoddyTech

Własne iteratory

Część sekcji Programowanie obiektowe ścieżki GDScript w Coddy. Lekcja 33 z 65.

Python sprawia, że klasa zachowuje się jak lista dzięki specjalnym metodom, takim jak __len__, __getitem__, __contains__ i __iter__. Godot udostępnia metody wirtualne tylko dla jednego z tych zastosowań: pętli for. Trzy metody sprawiają, że działa zapis for item in my_object::

  • _iter_init(iter) uruchamia się raz, przed pierwszym przebiegiem. Ustawia pozycję początkową i zwraca true, jeśli istnieje pierwszy element.
  • _iter_get(position) zwraca element z bieżącej pozycji, a zmienna pętli otrzymuje tę wartość.
  • _iter_next(iter) uruchamia się przed każdym kolejnym przebiegiem. Przechodzi do następnej pozycji i zwraca false, gdy nie ma już więcej elementów, co kończy pętlę.
# 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 to tablica z jednym miejscem, którą Godot tworzy dla każdej pętli. iter[0] przechowuje pozycję tej pętli, a Godot przekazuje jej wartość do _iter_get(). Team działa teraz w pętli for:

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

Przechowuj pozycję w iter[0], a nie w zmiennej składowej takiej jak _position. Każda pętla ma własne iter, więc dwie pętle przechodzące po tej samej drużynie, nawet gdy jedna znajduje się wewnątrz drugiej, nie zakłócają się nawzajem. W przypadku zmiennej składowej pętla wewnętrzna zmieniałaby pozycję pętli zewnętrznej.

Pozostałe operacje na listach nie mają wirtualnej metody: len(team) i team[0] są błędami. Napisz zwykłe metody o nazwach takich jak w przypadku tablicy, na przykład size(), get_at(index) i has(member). Nie sprawdzaj przynależności za pomocą in: "Ada" in team sprawdza, czy Team ma właściwość lub metodę o nazwie Ada, więc zwraca false.

challenge icon

Wyzwanie

Łatwy

Napisz klasę Bookshelf w pliku bookshelf.gd. Przechowuje tytuły w _titles i może przechowywać najwyżej _capacity książek:

  • add(title) dodaje tytuł na końcu i zwraca true albo zwraca false bez dodawania, gdy półka jest pełna lub zawiera już ten tytuł.
  • size() zwraca liczbę książek, a has(title) informuje, czy tytuł znajduje się na półce.
  • get_at(index) zwraca tytuł o podanym indeksie lub pusty ciąg, gdy indeks znajduje się poza zakresem półki.
  • _iter_init(), _iter_next() i _iter_get() umożliwiają pętli for przejście przez tytuły w kolejności, w jakiej zostały dodane.

Dostarczony kod odczytuje pojemność, liczbę tytułów i po jednym tytule w każdym wierszu, a następnie wyświetla tytuły, których nie udało się dodać. Wyświetla liczbę książek, wypisuje je za pomocą pętli for przechodzącej po półce, a następnie odczytuje jeszcze jeden tytuł i wyświetla informację, czy znajduje się on na półce, oraz tytuł ostatniej książki. Dla pojemności 3, tytułów Dune, Emma, Dune, Ulysses, Hamlet oraz wyszukiwanego tytułu Emma wyświetli:

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

Twój kod umieść w pliku bookshelf.gd. Plik main.gd zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

extends Node

func _ready():
	# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
	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 iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator GDScript online