attempt to compare number with nil / arithmetic on a nil value: ripara
Ripara 'attempt to compare number with nil' e 'arithmetic on a nil value' in FiveM: dati del giocatore non caricati, valori di config mancanti, tonumber e default sicuri con `or`.
Output della console:
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')Una riga dello script usa un valore che non esiste ancora in un confronto o un calcolo. Ecco cosa solitamente lascia il valore vuoto, e come rendere lo script sicuro.
Cosa significa l'errore
Lua ti dà nil per qualsiasi variabile o voce di tabella che non ha valore. Confrontare (<, >, <=) o calcolare (+, -, *, /) con nil ferma lo script con uno di questi messaggi:
attempt to compare number with nil(oattempt to compare nil with number): un lato del confronto ènil.attempt to perform arithmetic on a nil value: un calcolo usa una variabilenil. Quando Lua conosce il nome, lo aggiunge, come(field 'money')o(local 'price').
Il numero di riga nel messaggio è la riga con il confronto o la somma. nil è uno dei valori su quella riga. Stampali per vedere quale:
print('price', price, type(price))
print('count', count, type(count))
if price > count then
-- ...
end1. I dati del giocatore non sono caricati ancora
La causa più comune: lo script legge il giocatore prima che il framework abbia finito di caricarlo, ad esempio nelle prime righe di un file, o in un thread che si avvia immediatamente.
-- runs too early on the client: money is nil
local money = ESX.GetPlayerData().money
if money > 100 then
-- ...
endAspetta l'evento caricato del framework, e leggi i dati da lì:
-- 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)Sul server, un oggetto giocatore può essere nil anche quando l'id è sbagliato o il giocatore se ne è andato. Controllalo prima di usarlo:
local xPlayer = ESX.GetPlayerFromId(source)
if not xPlayer then return endlocal Player = QBCore.Functions.GetPlayer(source)
if not Player then return endSu QBox, l'equivalente è exports.qbx_core:GetPlayer(source), con lo stesso controllo nil.
Consiglio: se lo script viene riavviato mentre sei sul server,
playerLoadedha già sparato e non sparerà di nuovo. Leggi i dati una volta anche quando la risorsa si avvia.
2. Un valore di config è mancante
Hai aggiunto una riga a config.lua che lo script non ha, o lo script legge una chiave che la tua config più vecchia non contiene. Dopo un aggiornamento, una vecchia config.lua è una causa molto comune.
-- config.lua of the old version has no Config.Price
if playerMoney >= Config.Price then
-- ...
endConfronta la tua config con quella fornita con la nuova versione, e aggiungi le chiavi mancanti. Nel tuo codice, dai ad ogni impostazione un default:
local price = Config.Price or 1003. Il valore è una stringa, non un numero
I valori da un database, una casella di input in un menu o un messaggio JSON spesso arrivano come testo. Confrontare una stringa con un numero dà un errore diverso (attempt to compare number with string), ma una conversione che fallisce ti dà nil, il che riporta questo errore indietro. tonumber converte, e restituisce nil quando non può:
local amount = tonumber(data.amount)
if not amount then
return -- not a number: stop here
end4. Usa or per un default
or restituisce il lato destro quando il lato sinistro è nil (o false). È il modo più breve per rendere un calcolo sicuro:
local count = tonumber(data.count) or 0
local total = (item.price or 0) * countUsalo dove un valore mancante può davvero significare zero, come un bonus opzionale. Dove un valore mancante è un bug, ad esempio un prezzo che deve esistere, fermarsi con un messaggio chiaro invece di nasconderlo:
local price = Config.Items[name] and Config.Items[name].price
if not price then
print(('no price set for %s'):format(name))
return
end5. Un risultato di database o callback è vuoto
Una query che non trova alcuna riga dà nil o una tabella vuota. Leggere una colonna da essa fallisce:
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
-- ...
endControlla la riga per prima:
local row = MySQL.single.await('SELECT balance FROM bank WHERE owner = ?', { identifier })
local balance = row and row.balance or 0Lo stesso vale per callback server: la risposta può essere nil se il callback non è stato trovato o non ha restituito nulla. Se il tuo script aspetta su un callback, gestisci quel caso. Correlato: attempt to call a nil value è l'errore gemello quando una funzione, non un valore, è mancante.
6. Un errore di digitazione in un nome di field
xPlayer.money e xPlayer.Money sono diversi. Lo sono anche price e Price. Il messaggio di errore spesso chiama il field: controlla la sua ortografia rispetto alla documentazione del framework o rispetto alla tabella che stampi con print(json.encode(data)).
Elenco di controllo
| Sintomo | Correzione |
|---|---|
| Errore subito dopo l'unione | Aspetta l'evento giocatore caricato prima di leggere i dati del giocatore |
xPlayer o Player è nil sul server |
Controlla if not xPlayer then return end e l'id di sorgente |
| Errore dopo aver aggiornato uno script | Aggiungi le nuove chiavi della config.lua fornita alla tua |
| Il valore proviene da un menu o JSON | Converti con tonumber(value) e controlla che non sia nil |
| Un valore potrebbe mancare di proposito | Usa value or 0 come default |
| La query del database non restituisce nulla | Controlla che la riga non sia nil prima di leggere le sue colonne |
| Il field è nil anche se dovrebbe esistere | Controlla l'ortografia e le maiuscole |
Risposte rapide
Cosa significa 'attempt to compare number with nil'?
Una riga confronta un numero con qualcosa che non ha valore, come price > 100 quando price è nil. Trova quale variabile è nil e perché non è mai stata impostata.
Come do a una variabile un valore predefinito in Lua?
Usa or: local count = tonumber(value) or 0. Se il valore è nil o non è un numero, count diventa 0.
Perché succede solo subito dopo che mi unisco al server?
Lo script legge i dati del giocatore prima che il framework li abbia caricati. Aspetta l'evento giocatore caricato, o controlla che l'oggetto giocatore non sia nil prima di leggerlo.
Script senza questo problema
Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →
Pawn Shop AppUn banco dei pegni tra giocatori dentro lb-phone.Vedi script →
Quest CreatorUn editor visuale di missioni e dialoghi con gli NPC, costruito nodo per nodo in gioco.Vedi script →