Struktury kontrolne to instrukcje, które zarządzają przepływem wykonania kodu Luau. Istnieją cztery główne typy struktur kontrolnych:
- Instrukcja if then else wykonuje kod tylko wtedy, gdy określony warunek jest true. Wykonanie kodu nie powtarza się.
- Pętla while wykonuje kod tylko wtedy, gdy określony warunek jest true, i powtarza wykonanie, gdy warunek pozostaje true.
- Pętla repeat wykonuje kod i powtarza wykonanie, jeśli warunek jest true.
- Pętla for wykonuje kod ustaloną liczbę razy w zależności od określonych wejść.
Warunkiem dla instrukcji if, pętli while i pętli repeat może być dowolny wyrażenie lub wartość Luau. Jeśli wartość nie jest false ani nil, to Luau ocenia ją jako true w instrukcjach warunkowych. W przeciwieństwie do innych języków skryptowych, Luau uznaje zarówno zero, jak i pusty ciąg za true.
Instrukcje if
Podstawowa instrukcja if testuje swój warunek. Jeśli warunek jest prawdziwy, Luau wykonuje kod między then a end.
Możesz użyć instrukcji elseif, aby przetestować dodatkowe warunki, jeśli warunek if jest fałszywy. Możesz użyć instrukcji else, aby wykonać kod, jeśli wszystkie warunki if i elseif zawiodą. Części elseif i else są opcjonalne, ale nie możesz użyć żadnej z nich bez początkowej instrukcji if.
W łańcuchu warunków if, elseif i else, Luau testuje warunki od góry do dołu, zatrzymuje się na pierwszym warunku true i wykonuje kod, który go następuje.
if 2 + 2 == 5 then
print("Dwa plus dwa to pięć") -- Nie wypisuje, ponieważ warunek jest fałszywy
elseif 2 + 3 == 5 then
print("Dwa plus trzy to pięć") -- Dwa plus trzy to pięć
else
print("Wszystkie warunki zawiodły") -- Nie wypisuje, ponieważ poprzedni warunek jest prawdziwy
endPętle while
Pętla while—do ocenia, czy określony warunek jest prawdziwy czy fałszywy. Jeśli warunek jest false lub nil, to pętla kończy się, a Luau pomija kod w pętli. Jeśli warunek jest true, to Luau wykonuje kod w pętli i powtarza proces.
local czasPozostaly = 10
while czasPozostaly > 0 do
print("Pozostałe sekundy: " .. czasPozostaly)
task.wait(1)
czasPozostaly -= 1
end
print("Zegarek osiągnął zero!")
--[[ Wynik:
Pozostałe sekundy: 10
Pozostałe sekundy: 9
Pozostałe sekundy: 8
Pozostałe sekundy: 7
Pozostałe sekundy: 6
Pozostałe sekundy: 5
Pozostałe sekundy: 4
Pozostałe sekundy: 3
Pozostałe sekundy: 2
Pozostałe sekundy: 1
Zegarek osiągnął zero!
]]Pętle nieskończone
Możesz użyć pętli while—do, aby napisać nieskończone pętle gry, ustawiając true jako warunek.
while true do
print("Pętla...")
task.wait(0.5)
end
--[[ Wynik:
Pętla...
Pętla...
Pętla...
Pętla...
...
]]Pętle repeat
Pętla repeat—until powtarza, aż warunek będzie prawdziwy. Test warunkowy ocenia po uruchomieniu bloku kodu, więc blok kodu zawsze uruchamia się przynajmniej raz. W przeciwieństwie do innych języków, zakres Luau lokalnej zmiennej zadeklarowanej wewnątrz pętli repeat—until obejmuje warunek.
local aktualnaLiczbaGoblinów = 18
-- Spawn gobliny do maksymalnie 25 w grze
repeat
spawnGoblin()
aktualnaLiczbaGoblinów += 1
print("Aktualna liczba goblinów: " .. aktualnaLiczbaGoblinów)
until aktualnaLiczbaGoblinów == 25
print("Gobliny się rozmnożyły!")
--[[ Wynik:
Aktualna liczba goblinów: 19
Aktualna liczba goblinów: 20
Aktualna liczba goblinów: 21
Aktualna liczba goblinów: 22
Aktualna liczba goblinów: 23
Aktualna liczba goblinów: 24
Aktualna liczba goblinów: 25
Gobliny się rozmnożyły!
]]Pętle for
Pętla for wykonuje kod ustaloną liczbę razy, albo na podstawie licznika numerycznego, albo liczby elementów w kolekcji.
Numeryczne pętle for
Pętla for—do określa, ile razy wykonać pętlę, używając licznika. Pętla jest deklarowana z wartością początkową, wartością końcową i opcjonalnym przyrostem.
Luau ustawia licznik równy wartości początkowej, wykonuje blok kodu w pętli for, a następnie dodaje przyrost do licznika. Jeśli przyrost jest dodatni, proces powtarza się, aż licznik będzie równy lub większy od wartości końcowej. Jeśli przyrost jest ujemny, proces powtarza się, aż licznik będzie równy lub mniejszy od wartości końcowej.
Opcjonalny przyrost domyślnie wynosi 1. Nie musi być liczbą całkowitą.
for licznik = 1, 3 do
print(licznik)
end
--[[ Wynik:
1
2
3
]]
for licznik = 1, 6, 2 do
print(licznik)
end
--[[ Wynik:
1
3
5
]]
for licznik = 2, 0, -0.5 do
print(licznik)
end
--[[ Wynik:
2
1.5
1
0.5
0
]]Ogólne pętle for
Ogólna pętla for iteruje nad elementami w kolekcji, a nie nad ciągiem liczb. Dzięki ogólnym pętliom for, możesz wykonać kod dla każdego elementu w kolekcji i łatwo używać każdego elementu w kodzie.
Pętle for potrzebują funkcji lub iteratora, aby iterować po różnych typach kolekcji. Globalna funkcja ipairs() zwraca iterator dla tablic, a globalna funkcja pairs() zwraca iterator dla słowników. Biblioteka string zapewnia string.gmatch() do iteracji po łańcuchach.
Uogólniona iteracja
W Luau możesz iterować po tabeli, używając słowa kluczowego in bezpośrednio w tabeli, zamiast używać funkcji iteratora, takiej jak ipairs():
for i, v in {1, 2, 3, 4, 5} do
print(i, v)
endUogólniona iteracja pozwala również użyć metody metametod dla __iter, aby stworzyć niestandardową funkcję iteratora. Ten uproszczony przykład iteruje po tablicy w odwrotnej kolejności, od jej ostatniego elementu do pierwszego:
local myTable = {1, 2, 3, 4, 5}
myMetatable = {
__iter = function(t)
local i = #t + 1
return function()
i -= 1
if i > 0 then
return i, t[i]
end
end
end,
}
setmetatable(myTable, myMetatable)
for i, v in myTable do
print(i, v)
end
--[[ Wynik:
5 5
4 4
3 3
2 2
1 1
]]Tablice
Funkcja ipairs() zwraca iterator, który iteruje przez numeryczne indeksy w tabeli i zwraca indeks i wartość dla każdego elementu. Czyni to odpowiednim dla tablic, gdzie wszystkie indeksy są numeryczne.
local tablica = {"a", "b", "c", "d", "e"}
for indeks, wartosc in ipairs(tablica) do
print(indeks, wartosc)
end
--[[ Wynik:
1 a
2 b
3 c
4 d
5 e
]]Słowniki
Funkcja pairs() zwraca iterator, który iteruje przez wszystkie indeksy (w tym numeryczne indeksy) w tabeli i zwraca klucz i wartość dla każdego wpisu w słowniku. Kolejność przechodzenia przez elementy w tabeli słownikowej jest przypadkowa. Czynią to odpowiednim do iteracji po słownikach, gdzie elementy są przechowywane w nieuporządkowanej postaci z indeksami nie-numerycznymi.
local slownik = {
[1] = "a",
["Witaj"] = "b",
[5] = "c",
[true] = "d",
["Świat"] = "f",
[false] = "e"
}
for klucz, wartosc in pairs(slownik) do
print(klucz, wartosc)
end
--[[ Wynik:
Witaj b
true d
false e
Świat f
5 c
1 a
]]Przerwanie pętli
Aby zmusić pętlę do zakończenia, użyj słowa kluczowego break. Poniższy fragment kodu pokazuje, jak przerwać nieskończoną pętlę while—do.
local sekundyUplynely = 0
local limitCzasu = 5
while true do
task.wait(1)
sekundyUplynely += 1
print("Upłynęło sekund:", sekundyUplynely)
if sekundyUplynely == limitCzasu then
break
end
end
print("Pięć sekund minęło. Czas ruszyć dalej!")
--[[ Wynik:
1
2
3
4
5
Pięć sekund minęło. Czas ruszyć dalej!
]]Kontynuowanie pętli
Aby zmusić pętlę do iteracji i ponownego rozpoczęcia, użyj słowa kluczowego continue. Pętla for będzie iterować licznik; while i repeat—until sprawdzą warunek pętli przed kontynuowaniem. Poniższy przykład kodu pobiera wszystkie dzieci Instance określonego ClassName.
local function GetChildrenOfClass(parent: Instance, className: string): {Instance}
local children = {}
for _, child in parent:GetChildren() do
if child.ClassName ~= className then continue end -- Iteruje pętlę
table.insert(children, child)
end
return children
end