Versuche, Zahl mit nil zu vergleichen / Arithmetik mit nil: Behebung
Behebe 'attempt to compare number with nil' und 'arithmetic on a nil value' in FiveM: ungeladene Spielerdaten, fehlende Konfigurationswerte, tonumber und sichere Voreinstellungen mit `or`.
Konsolenausgabe:
SCRIPT ERROR: @my_script/server/main.lua:58: attempt to compare number with nil
SCRIPT ERROR: @my_script/client/main.lua:91: attempt to perform arithmetic on a nil value (field 'money')Eine Zeile des Skripts verwendet einen Wert, der noch nicht in einem Vergleich oder einer Berechnung existiert. Hier ist, was normalerweise den Wert leer lässt, und wie man das Skript sicher macht.
Was der Fehler bedeutet
Lua gibt dir nil für alle Variablen oder Tabelleneingaben, die keinen Wert haben. Das Vergleichen (<, >, <=) oder Berechnen (+, -, *, /) mit nil stoppt das Skript mit einer dieser Meldungen:
attempt to compare number with nil(oderattempt to compare nil with number): eine Seite des Vergleichs istnil.attempt to perform arithmetic on a nil value: eine Berechnung verwendet einenil-Variable. Wenn Lua den Namen kennt, fügt es ihn hinzu, wie(field 'money')oder(local 'price').
Die Zeilennummer in der Meldung ist die Zeile mit dem Vergleich oder der Summe. Das nil ist einer der Werte auf dieser Zeile. Drucke sie aus, um zu sehen, welcher:
print('price', price, type(price))
print('count', count, type(count))
if price > count then
-- ...
end1. Spielerdaten werden nicht geladen
Die häufigste Ursache: Das Skript liest den Spieler, bevor das Framework sie fertig geladen hat, zum Beispiel in den ersten Zeilen einer Datei, oder in einem Thread, der sofort startet.
-- runs too early on the client: money is nil
local money = ESX.GetPlayerData().money
if money > 100 then
-- ...
endWarte auf das geladene Event des Frameworks und lies die Daten von dort:
-- ESX client
local PlayerData = {}
RegisterNetEvent('esx:playerLoaded', function(xPlayer)
PlayerData = xPlayer
end)-- QBCore client
local QBCore = exports['qb-core']:GetCoreObject()
local PlayerData = {}
RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function()
PlayerData = QBCore.Functions.GetPlayerData()
end)Auf dem Server kann ein Spieler-Objekt auch nil sein, wenn die ID falsch ist oder der Spieler gegangen ist. Überprüfe es, bevor du es verwendest:
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return endlocal Player = QBCore.Functions.GetPlayer(source)
if not Player then return endAuf QBox ist das Äquivalent exports.qbx_core:GetPlayer(source), mit der gleichen nil-Überprüfung.
Tipp: Wenn das Skript neu gestartet wird, während du auf dem Server bist, hat
playerLoadedbereits ausgelöst und wird nicht wieder auslösen. Lies die Daten auch einmal, wenn die Ressource startet.
2. Ein Konfigurationswert fehlt
Du hast eine Zeile zu config.lua hinzugefügt, die das Skript nicht hat, oder das Skript liest einen Schlüssel, den deine ältere Config nicht enthält. Nach einem Update ist ein alter config.lua eine sehr häufige Ursache.
-- config.lua of the old version has no Config.Price
if playerMoney >= Config.Price then
-- ...
endVergleiche deine Config mit der, die mit der neuen Version versendet wird, und füge die fehlenden Schlüssel hinzu. In deinem eigenen Code gib jeder Einstellung eine Voreinstellung:
local price = Config.Price or 1003. Der Wert ist ein String, keine Zahl
Werte aus einer Datenbank, einer Eingabebox in einem Menü oder einer JSON-Nachricht kommen oft als Text an. Das Vergleichen eines Strings mit einer Zahl gibt einen anderen Fehler (attempt to compare number with string), aber eine Konvertierung, die schlägt fehl, gibt dir nil, das bringt diesen Fehler zurück. tonumber konvertiert und gibt nil zurück, wenn es nicht kann:
local amount = tonumber(data.amount)
if not amount then
return -- not a number: stop here
end4. Verwende or für eine Voreinstellung
or gibt die rechte Seite zurück, wenn die linke Seite nil (oder false) ist. Es ist der kürzeste Weg, eine Berechnung sicher zu machen:
local count = tonumber(data.count) or 0
local total = (item.price or 0) * countVerwende es, wo ein fehlender Wert wirklich Null bedeuten kann, wie ein optionaler Bonus. Wo ein fehlender Wert ein Bug ist, zum Beispiel ein Preis, der existieren muss, stoppe mit einer klaren Nachricht, anstatt ihn zu verstecken:
local price = Config.Items[name] and Config.Items[name].price
if not price then
print(('no price set for %s'):format(name))
return
end5. Ein Datenbank- oder Callback-Ergebnis ist leer
Eine Abfrage, die keine Zeile findet, gibt nil oder eine leere Tabelle. Das Lesen einer Spalte davon schlägt fehl:
local row = MySQL.single.await('SELECT balance FROM bank WHERE owner = ?', { identifier })
if row.balance > 0 then -- row is nil when the player has no row
-- ...
endÜberprüfe die Zeile zuerst:
local row = MySQL.single.await('SELECT balance FROM bank WHERE owner = ?', { identifier })
local balance = row and row.balance or 0Das gleiche gilt für Server-Callbacks: Die Antwort kann nil sein, wenn der Callback nicht gefunden wurde oder nichts zurückgab. Wenn dein Skript auf einen Callback wartet, verwalte diesen Fall. Verwandt: attempt to call a nil value ist der Geschwister-Fehler, wenn eine Funktion, nicht ein Wert, fehlt.
6. Ein Tippfehler in einem Feldnamen
xPlayer.money und xPlayer.Money sind unterschiedlich. Das gleiche mit price und Price. Die Fehlermeldung nennt oft das Feld: überprüfe seine Rechtschreibung gegen die Framework-Dokumentation oder gegen die Tabelle, die du mit print(json.encode(data)) druckst.
Checkliste
| Symptom | Behebung |
|---|---|
| Fehler direkt nach dem Beitritt | Warte auf das Spieler-geladenes Event, bevor du Spielerdaten liest |
xPlayer oder Player ist nil auf dem Server |
Überprüfe if not xPlayer then return end und die Quell-ID |
| Fehler nach dem Aktualisieren eines Skripts | Füge die neuen Schlüssel des versendeten config.lua zu deinem hinzu |
| Wert kommt von einem Menü oder JSON | Konvertiere mit tonumber(value) und überprüfe, dass es nicht nil ist |
| Ein Wert kann absichtlich fehlen | Verwende value or 0 als Voreinstellung |
| Datenbankabfrage gibt nichts zurück | Überprüfe, dass die Zeile nicht nil ist, bevor du ihre Spalten liest |
| Feld ist nil, obwohl es existieren sollte | Überprüfe die Rechtschreibung und Großbuchstaben |
Kurze Antworten
Was bedeutet 'attempt to compare number with nil'?
Eine Zeile vergleicht eine Zahl mit etwas, das keinen Wert hat, wie price > 100, wenn price nil ist. Finde heraus, welche Variable nil ist und warum sie nie gesetzt wurde.
Wie gebe ich einer Variable einen Standardwert in Lua?
Verwende or: local count = tonumber(value) or 0. Wenn der Wert nil oder keine Zahl ist, wird count zu 0.
Warum passiert es nur direkt, nachdem ich dem Server beigetreten bin?
Das Skript liest Spielerdaten, bevor das Framework sie geladen hat. Warte auf das Spieler-geladenes Event oder überprüfe, dass das Spieler-Objekt nicht nil ist, bevor du davon liest.
Scripts ohne dieses Problem
Shop CreatorBau einen Shop in unter einer Minute — Besitzer, Angestellte, Tresore und Überfälle inklusive.Script ansehen →
Pawn Shop AppEin Pfandmarkt zwischen Spielern, direkt in lb-phone.Script ansehen →
Quest CreatorEin visueller Editor für Quests und NPC-Dialoge, Node für Node im Spiel gebaut.Script ansehen →