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.