Menu
CoddyTech

Iterator Kalıbı

Coddy'nin Lua Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 64 / 70.

Bir nesnenin içinde depolanmış bir öğe koleksiyonun olduğunda, genellikle bu öğeler üzerinde döngü kurmak istersin. Lua'nın genel for döngüsü herhangi bir yineleyici işlevle çalışır: her yinelemeden önce işlevi çağırır ve işlev nil döndürdüğünde durur.

Yineleyici kalıbı, nesneye böyle bir işlev döndüren bir yöntem verir. İşlev, konumunu yerel bir değişkende tutar; böylece konum koleksiyona değil, tek bir döngüye ait olur:

local Collection = {}
Collection.__index = Collection

function Collection:new()
    local obj = { items = {} }
    setmetatable(obj, Collection)
    return obj
end

function Collection:add(item)
    table.insert(self.items, item)
end

function Collection:iter()
    local index = 0
    return function()
        index = index + 1
        return self.items[index]
    end
end

bag:iter() işlevinin her çağrısı, 0 değerinden başlayan kendi index değişkenine sahip yeni bir işlev oluşturur. Bu işlev bir kapatmadır: iter döndükten sonra da index ve self değerlerini kullanabilir. Son öğeden sonra self.items[index] değeri nil olur ve döngü durur:

local bag = Collection:new()
bag:add("apple")
bag:add("banana")

for item in bag:iter() do
    print(item)  -- apple, ardından banana
end

for item in bag:iter() do
    print(item)  -- yine apple, ardından banana
end

Konumu koleksiyonun kendisinde tutmayın. Saklanan nesne self.index değerini tutup kendi yineleyicisi olarak davransaydı, ilk döngü indeksi sona getirirdi; böylece ikinci döngü hiçbir şey yazdırmazdı ve break ile erken sonlanan bir döngü, sonraki döngünün ortadan başlamasına neden olurdu.

challenge icon

Görev

Kolay

Lua'nın genel amaçlı for döngüsüyle üzerinde dolaşabileceğin bir Playlist sınıfı oluşturalım! Bir yineleyici işlevi döndüren :iter() yöntemiyle Iterator kalıbını uygulayacaksın.

Kodunu iki dosyaya ayıracaksın:

  • Playlist.lua: Şarkıları kendi içinde saklayan bir Playlist sınıfı oluştur. Sınıfının boş bir şarkı listesi başlatan bir :new() kurucusuna ve listeye şarkı ekleyen bir :addSong(title) yöntemine ihtiyacı var. En önemlisi, her çağrıldığında yeni bir işlev döndüren bir :iter() yöntemi ekle. Bu işlev, konumunu yerel bir değişkende tutar ve her çağrıda sıradaki şarkıyı döndürür; başka şarkı kalmadığında ise nil döndürür.
  • main.lua: Playlist modülünü require et ve yeni bir çalma listesi oluştur. Aldığın girdilere göre listeye şarkılar ekle, ardından her şarkı başlığını kendi satırında yazdırmak için playlist:iter() üzerinde genel amaçlı bir for döngüsü kullan.

:iter() yönteminin her çağrısı ilk şarkıdan başladığı için aynı çalma listesinin üzerinde istediğin sayıda dolaşabilirsin.

Çalma listene eklenecek şarkı başlıklarını temsil eden üç girdi alacaksın (sırasıyla).

Örneğin girdiler Bohemian Rhapsody, Stairway to Heaven ve Hotel California ise çıktı şöyle olmalıdır:

Bohemian Rhapsody
Stairway to Heaven
Hotel California

Girdiler Yesterday, Imagine ve Let It Be ise çıktı şöyle olmalıdır:

Yesterday
Imagine
Let It Be

Kendin dene

-- Playlist modülünü require ile yükle
local Playlist = require('Playlist')

-- Girdiden üç şarkı adı oku
local song1 = io.read()
local song2 = io.read()
local song3 = io.read()

-- TODO: Playlist:new() kullanarak yeni bir çalma listesi oluştur

-- TODO: :addSong() kullanarak üç şarkıyı çalma listesine ekle

-- TODO: playlist:iter() üzerinde genel bir for döngüsü kullan
-- ve her şarkı adını ayrı bir satıra yazdır
-- İpucu: for song in playlist:iter() do ... end
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Yönelimli Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online Lua derleyicisi