table index is nil / attempt to index a nil value (field): naprawa Lua FiveM
Napraw 'table index is nil' i 'attempt to index a nil value (field x)' w Lua FiveM – brakujące klucze config, przypisania t[nil], zagnieżdżone tabele i bezpieczne wzorce dostępu.
Dwa błędy, które wyglądają podobnie, pojawiają się cały czas w skryptach FiveM:
SCRIPT ERROR: @my_script/server/main.lua:42: table index is nil
SCRIPT ERROR: @my_script/client/main.lua:19: attempt to index a nil value (field 'shops')Oznaczają różne rzeczy. Pierwsza dotyczy nil klucza, druga nil tabeli. Oba sprowadzają się do wartości, którą spodziewał się twój kod i nie znalazł. Ten przewodnik pokazuje, jak je rozróżnić i jak napisać dostęp, aby nie mógł się zawiesić.
table index is nil
Przypisałeś do tabeli, a klucz był nil:
local cache = {}
local function remember(identifier, data)
cache[identifier] = data -- table index is nil when identifier is nil
endLua pozwala każdą wartość jako klucz, oprócz nil (i NaN). Czytanie cache[nil] po prostu daje nil, ale pisanie do niego podnosi błąd.
Znajdź, której zmiennej między nawiasami jest nil na tej linii. Zwyczajne źródła:
- Szukanie gracza, które nic nie zwróciło.
GetPlayerIdentifierByType(source, 'license')zwracanil, gdy gracz nie ma identyfikatora tego typu, na przykład gdy gracz nie jest połączony przez platformę, którą oczekujesz. - Zły
source. Na serwerze sprawdzaj, czy zdarzenie naprawdę pochodzi od gracza. Wezwanie z konsoli nie ma gracza za nim. - Pole brakujące w danych:
data.idjest nil, ponieważ wysyłający użyłdata.Id.
Wydrukuj to, aby być pewnym:
print('identifier', identifier, type(identifier))Następnie zatrzymaj przypisanie, gdy klucz brakuje i zdecyduj, czy to błąd czy normalny przypadek:
local function remember(identifier, data)
if not identifier then
return print('remember: no identifier, skipping')
end
cache[identifier] = data
endattempt to index a nil value (field 'x')
attempt to index a nil value (field 'shops')Tutaj tabela brakuje. Nazwa w nawiasach to pole, które było nil, a rzecz, którą go indeksowałeś, jest na linii:
local first = Config.shops[1] -- Config.shops is nil, so [1] failsLua wymienia to, co wie. Kilka form, które zobaczysz:
| Wiadomość | Znaczenie |
|---|---|
(global 'Config') |
Zmienna globalna Config jest nil |
(local 'data') |
Zmienna lokalna jest nil, często argument funkcji |
(field 'shops') |
Config.shops jest nil |
(field '?') |
Tabela znaleziona przez klucz zmiennej, takie jak Config.Shops[id], jest nil |
(upvalue 'cache') |
Zmienna ze zewnętrznego zakresu jest nil |
Dla field '?', Lua nie może nazwać klucza, ponieważ jest obliczony:
Config.Shops[id].label -- attempt to index a nil value (field '?')Naprawa jest taka sama: znajdź, który krok łańcucha jest nil. Wydrukuj każdy krok:
print(Config)
print(Config.Shops)
print(Config.Shops[id])Zagnieżdżone tabele config
Większość tych błędów pochodzi z plików config:
Config = {}
Config.Shops = {
bar = { label = 'Bar', items = { 'beer', 'water' } },
}
-- somewhere else
local items = Config.Shops[shopName].itemsJeśli shopName to 'Bar' zamiast 'bar', Config.Shops[shopName] jest nil i dalsze .items zawali. Przyczyny do sprawdzenia:
- Inna pisownia lub wielkość liter. Klucze Lua są czułe na wielkość liter.
- Plik config nie jest załadowany. Musi być w
shared_scripts(lub na właściwej liście boku)fxmanifest.lua, przed plikiem, który go czyta. - Config jest zdefiniowany tylko po jednej stronie. Plik wymieniony pod
server_scriptsjest niewidoczny dla klienta. - Klucz numeryczny względem klucza stringowego.
Config.Shops[1]iConfig.Shops['1']to różne wpisy. Zdarza się to często, gdy dane przechodzą przez JSON, przeczytaj błędy json.decode FiveM.
-- fxmanifest.lua
shared_scripts { 'config.lua' }
client_scripts { 'client/*.lua' }
server_scripts { 'server/*.lua' }Wzorce bezpiecznego dostępu
Gdy brakująca wartość jest normalnym przypadkiem, napisz dostęp, aby to obsługiwał.
Sprawdzaj każdy krok za pomocą and:
local shop = Config.Shops and Config.Shops[shopName]
if not shop then
return print(('Unknown shop: %s'):format(tostring(shopName)))
end
print(shop.label)Używaj or dla domyślnego:
local items = (shop and shop.items) or {}
local radius = Config.Radius or 5.0Utwórz małego helpera, gdy często czytasz głębokie ścieżki:
local function get(t, ...)
for _, key in ipairs({ ... }) do
if type(t) ~= 'table' then return nil end
t = t[key]
end
return t
end
local label = get(Config, 'Shops', shopName, 'label')Ostrzeżenie: nie ukrywaj każdego nil za pomocą
or {}. Jeśli tabela, która musi istnieć, brakuje, to błąd w config lub kolejności ładowania i ciche fallback tylko przenosi błąd gdzieś mniej oczywisty. Używaj osłon dla wartości, które mogą być uzasadnione nieobecne.
Zrzuć tabelę, aby zobaczyć, co jest wewnątrz
Gdy nie jesteś pewien, co tabela zawiera, wydrukuj ją jako JSON:
print(json.encode(Config.Shops, { indent = true }))Zobaczysz rzeczywiste klucze i dostrzeżesz literówkę, inną wielkość liter lub liczbę, gdzie spodziewałeś się stringa. Zrób to w punkcie, gdzie błąd się zdarza, a nie na górze pliku, ponieważ dane mogą być wypełniane później.
Lista kontrolna
| Objaw | Naprawa |
|---|---|
table index is nil |
Klucz w t[key] = value jest nil; wydrukuj go i wróć wcześnie, jeśli brakuje |
attempt to index a nil value (field 'shops') |
Wymienione pole nie jest ustawione w tabeli przed nim; sprawdzaj nazwę i pisownię |
attempt to index a nil value (field '?') |
Szukanie ze zmiennym kluczem nic nie znalazło; sprawdzaj klucz i jego wielkość liter |
| Działa na serwerze, nil na kliencie | Config nie jest w shared_scripts |
| Plik config ignorowany | Wymień go przed plikami, które go używają |
| Klucz liczbowy kontra klucz stringowy | [1] i ['1'] różnią się; konwertuj za pomocą tonumber lub tostring |
Aby uzyskać inne typowe wiadomości nil, przeczytaj attempt to compare nil i błędy złych argumentów.
Szybkie odpowiedzi
Co oznacza 'table index is nil'?
Skrypt próbował napisać do tabeli, używając nil jako klucza, takie jak t[key] = value, gdy key jest nil. Lua nie pozwala nil jako klucza, więc się zatrzymuje.
Jaka jest różnica między 'table index is nil' i 'attempt to index a nil value'?
W 'table index is nil' klucz jest nil. W 'attempt to index a nil value' sama tabela jest nil, więc nie ma niczego do przeczytania lub napisania.
Dlaczego błąd mówi pole '?' zamiast nazwy?
Gdy klucz to zmienna, taka jak Config.Shops[id], Lua nie może go nazwać. Pokazuje ?. Spójrz na linię i znajdź, która część łańcucha jest nil.
Skrypty bez tego problemu
Shop CreatorZbuduj sklep w niecałą minutę — właściciele, pracownicy, sejfy i napady w zestawie.Zobacz skrypt →
Quest CreatorWizualny edytor questów i dialogów z NPC, budowanych węzeł po węźle w grze.Zobacz skrypt →
Item Creator V2Twórz używalne przedmioty z animacjami, propami, efektami i nie tylko — bez pisania kodu.Zobacz skrypt →