Lua - Trình lặp lại

Iterator là một cấu trúc cho phép bạn duyệt qua các phần tử của cái gọi là bộ sưu tập hoặc vùng chứa. Trong Lua, các tập hợp này thường tham chiếu đến các bảng, được sử dụng để tạo các cấu trúc dữ liệu khác nhau như mảng.

Chung cho Trình lặp lại

Một trình lặp chung cho trình lặp cung cấp các cặp giá trị khóa của mỗi phần tử trong bộ sưu tập. Một ví dụ đơn giản được đưa ra dưới đây.

array = {"Lua", "Tutorial"}

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

Khi chúng ta chạy đoạn mã trên, chúng ta sẽ nhận được kết quả sau:

1  Lua
2  Tutorial

Ví dụ trên sử dụng hàm vòng lặp ipairs mặc định do Lua cung cấp.

Trong Lua, chúng tôi sử dụng các hàm để biểu diễn các trình vòng lặp. Dựa trên việc duy trì trạng thái trong các hàm của trình vòng lặp này, chúng ta có hai kiểu chính:

  • Trình lặp không trạng thái
  • Trình lặp trạng thái

Trình lặp không trạng thái

Bản thân cái tên chúng ta có thể hiểu rằng loại hàm vòng lặp này không giữ lại bất kỳ trạng thái nào.

Bây giờ chúng ta hãy xem một ví dụ về việc tạo trình vòng lặp của riêng mình bằng cách sử dụng một hàm đơn giản in ra các hình vuông của n những con số.

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

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

1	1
2	4
3	9

Đoạn mã trên có thể được sửa đổi một chút để bắt chước cách hoạt động của hàm ipairs của trình vòng lặp. Nó được hiển thị bên dưới.

function square(iteratorMaxCount,currentNumber)

   if currentNumber<iteratorMaxCount
   then
      currentNumber = currentNumber+1
      return currentNumber, currentNumber*currentNumber
   end
	
end

function squares(iteratorMaxCount)
   return square,iteratorMaxCount,0
end  

for i,n in squares(3)
do 
   print(i,n)
end

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

1	1
2	4
3	9

Trình lặp trạng thái

Ví dụ trước về phép lặp sử dụng hàm không giữ lại trạng thái. Mỗi lần hàm được gọi, nó sẽ trả về phần tử tiếp theo của bộ sưu tập dựa trên biến thứ hai được gửi đến hàm. Để giữ trạng thái của phần tử hiện tại, các bao đóng được sử dụng. Đóng cửa giữ lại các giá trị biến trên các lệnh gọi hàm. Để tạo một bao đóng mới, chúng ta tạo hai hàm bao gồm chính nó và một nhà máy, hàm tạo ra bao đóng.

Bây giờ chúng ta hãy xem một ví dụ về việc tạo trình lặp của riêng chúng ta, trong đó chúng ta sẽ sử dụng các bao đóng.

array = {"Lua", "Tutorial"}

function elementIterator (collection)

   local index = 0
   local count = #collection
	
   -- The closure function is returned
	
   return function ()
      index = index + 1
		
      if index <= count
      then
         -- return the current element of the iterator
         return collection[index]
      end
		
   end
	
end

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

Khi chúng ta chạy chương trình trên, chúng ta sẽ nhận được kết quả sau.

Lua
Tutorial

Trong ví dụ trên, chúng ta có thể thấy rằng elementIterator có một phương thức khác bên trong sử dụng chỉ số các biến bên ngoài cục bộ và đếm để trả về từng phần tử trong bộ sưu tập bằng cách tăng chỉ số mỗi khi hàm được gọi.

Chúng ta có thể tạo các trình vòng lặp hàm của riêng mình bằng cách sử dụng hàm đóng như được hiển thị ở trên và nó có thể trả về nhiều phần tử cho mỗi lần chúng ta lặp qua bộ sưu tập.