Lua iterator


Interator ialah objek yang boleh digunakan untuk melintasi beberapa atau semua elemen dalam bekas perpustakaan templat standard Setiap objek lelaran mewakili alamat tertentu dalam bekas

Dalam Lua, iterator ialah. struktur yang menyokong jenis penunjuk, yang boleh merentasi setiap elemen koleksi.


Generik untuk lelaran

Generik untuk menyimpan fungsi lelaran secara dalaman, ia menyimpan tiga nilai: fungsi lelaran, pemalar keadaan dan pembolehubah kawalan.

Generik untuk iterator menyediakan pasangan kunci/nilai bagi koleksi Format sintaks adalah seperti berikut:

for k, v in pairs(t) do
    print(k, v)
end

Dalam kod di atas, k dan v ialah senarai pembolehubah; ialah senarai ungkapan.

Lihat contoh berikut:

array = {"Lua", "Tutorial"}

for key,value in ipairs(array) 
do
   print(key, value)
end

Output pelaksanaan kod di atas ialah:

1  Lua
2  Tutorial

Dalam contoh di atas, kami menggunakan ipairs fungsi lelaran yang disediakan oleh Lua secara lalai.

Mari kita lihat proses pelaksanaan normatif untuk:

  • Pertama, mulakan dan hitung nilai ungkapan selepas masuk. Ungkapan harus mengembalikan apa normatif untuk memerlukan. Tiga nilai: fungsi lelaran, pemalar keadaan, pembolehubah kawalan sama seperti tugasan berbilang nilai, jika bilangan hasil yang dikembalikan oleh ungkapan kurang daripada tiga, ia akan diisi secara automatik dengan nil, dan lebihan akan diabaikan .

  • Kedua, panggil fungsi lelaran dengan pemalar keadaan dan pembolehubah kawalan sebagai parameter (nota: untuk struktur, pemalar keadaan tidak berguna, cuma dapatkan nilainya semasa pemulaan dan hantar ke fungsi lelaran).

  • Ketiga, tetapkan nilai yang dikembalikan oleh fungsi lelaran kepada senarai pembolehubah.

  • Keempat, jika nilai pertama yang dikembalikan adalah sifar, gelung akan tamat, jika tidak, badan gelung akan dilaksanakan.

  • Kelima, kembali ke langkah kedua dan panggil fungsi lelaran

sekali lagi. Dalam Lua, kita sering menggunakan fungsi untuk menerangkan iterator Setiap kali fungsi dipanggil, elemen koleksi seterusnya dikembalikan. Peulang Lua termasuk dua jenis berikut:

  • Peulang tanpa status

  • Peulang berbilang keadaan


Peulang tanpa status

Peulang tanpa status merujuk kepada peulang yang tidak mengekalkan sebarang keadaan, jadi dalam satu gelung kita boleh menggunakan iterator tanpa kewarganegaraan untuk mengelak daripada membuat penutupan Kos tambahan.

Setiap lelaran, fungsi lelaran dipanggil dengan nilai dua pembolehubah (pemalar keadaan dan pembolehubah kawalan) sebagai parameter Penyalur tanpa kewarganegaraan hanya menggunakan dua nilai ini untuk mendapatkan elemen seterusnya.

Contoh mudah tipikal jenis lelaran tanpa kewarganegaraan ini ialah ipairs, yang merentasi setiap elemen tatasusunan.

Dalam contoh berikut, kami menggunakan fungsi mudah untuk melaksanakan iterator dan merealisasikan kuasa dua nombor n:

function square(iteratorMaxCount,currentNumber)
   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
   return currentNumber, currentNumber*currentNumber
   end
end

for i,n in square,3,0
do
   print(i,n)
end

Hasil keluaran contoh di atas ialah:

1	1
2	4
3	9

Status lelaran termasuk Jadual yang dilalui (nyatakan pemalar yang tidak akan berubah semasa gelung) dan subskrip indeks semasa (pembolehubah kawalan), ipairs dan fungsi lelaran adalah sangat mudah. ​​Kita boleh melaksanakannya dalam Lua seperti ini:

function iter (a, i)
    i = i + 1
    local v = a[i]
    if v then
       return i, v
    end
end
 
function ipairs (a)
    return iter, a, 0
end

Apabila Lua memanggil ipairs(a) untuk memulakan gelung, ia mendapat tiga nilai: fungsi lelaran iter, nyatakan pemalar a, dan mengawal nilai awal pembolehubah 0, kemudian Lua memanggil iter(a,0) untuk mengembalikan 1,a [1 ] (kecuali a[1]=nil); lelaran kedua memanggil iter(a,1) untuk mengembalikan 2, a[2]... sehingga unsur nil pertama.


Peulang berbilang keadaan

Dalam banyak kes, iterator perlu menyimpan berbilang maklumat keadaan dan bukannya pemalar keadaan mudah dan mengawal pembolehubah Cara paling mudah ialah menggunakan penutupan , dan kaedah lain adalah untuk merangkum semua maklumat status ke dalam jadual dan menggunakan jadual sebagai pemalar status lelaran Kerana dalam kes ini semua maklumat boleh disimpan dalam jadual, fungsi lelaran biasanya tidak memerlukan parameter kedua.


Dalam contoh berikut kami mencipta iterator kami sendiri:

array = {"Lua", "Tutorial"}

function elementIterator (collection)
   local index = 0
   local count = #collection
   -- 闭包函数
   return function ()
      index = index + 1
      if index <= count
      then
         --  返回迭代器的当前元素
         return collection[index]
      end
   end
end

for element in elementIterator(array)
do
   print(element)
end

Hasil keluaran contoh di atas ialah:

Lua
Tutorial

Dalam contoh di atas kita boleh Seperti yang anda lihat, fungsi penutupan digunakan dalam elementIterator untuk mengira saiz set dan output setiap elemen.