Skyddade anrop med pcall
Fånga fel säkert med pcall och tolka returvärdena.
Skyddade anrop med pcall är en gratis lektion i Lua Academy på CoddyKit. Detta är lektion 2 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Lua Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Lua Academy innehåller totalt 4 lektioner.
Grunderna i pcall
pcall(f, ...) anropar funktionen f med argumenten ... i skyddat läge. Om f lyckas returnerar pcall true följt av alla returvärden. Om f ger ett fel returnerar pcall false följt av felmeddelandet. Programmet fortsätter i båda fallen.
local function risky(x)
if x < 0 then error("negative input: " .. x) end
return math.sqrt(x)
end
local ok, result = pcall(risky, 9)
print(ok, result) -- true 3.0
ok, result = pcall(risky, -1)
print(ok, result) -- false ...: negative input: -1Fånga specifika fel
Kontrollera felvärdets typ efter pcall för att hantera olika feltyper på olika sätt. Tabellfel innehåller strukturerade data, medan strängfel innehåller ett meddelande. Hantera alltid båda fallen.
local function op(errType)
if errType == "table" then
error({code=42, msg="structured error"})
else
error("plain string error")
end
end
local ok, err = pcall(op, "table")
if not ok then
if type(err) == "table" then
print("Code:", err.code, "Msg:", err.msg)
else
print("String error:", err)
end
endFlera returvärden vid lyckat resultat
Vid lyckat resultat returnerar pcall alla den skyddade funktionens returvärden efter det inledande true. Fånga dem i flera variabler.
local function compute(a, b)
return a + b, a * b, a - b
end
local ok, sum, product, diff = pcall(compute, 6, 4)
if ok then
print("sum:", sum, "product:", product, "diff:", diff)
-- sum: 10 product: 24 diff: 2
endKapsla pcall
pcall-anrop kan kapslas i varandra. Varje pcall skapar ett oberoende skyddat område. Ett fel i en inre pcall fångas av den inre pcall-en, inte den yttre. På så sätt kan ni implementera reservstrategier.
local function tryPrimary()
error("primary failed")
end
local function tryFallback()
return "fallback result"
end
local ok, result = pcall(tryPrimary)
if not ok then
print("Primary failed:", result)
ok, result = pcall(tryFallback)
end
if ok then print("Got:", result) end -- fallback resultpcall med metoder
För att anropa en metod (kolonsyntax) via pcall skickar ni funktionen och objektet som det första argumentet. pcall(obj.method, obj, args...) eller så omsluter ni anropet i en closure.
local obj = {
x = 10,
compute = function(self, n)
if n == 0 then error("zero divisor") end
return self.x / n
end
}
-- Pass method + self explicitly
local ok, v = pcall(obj.compute, obj, 2)
print(ok, v) -- true 5.0
-- Or use a closure
ok, v = pcall(function() return obj:compute(0) end)
print(ok, v) -- false ...zero divisorpcall för säker I/O
Omslut I/O-operationer med pcall för att fånga oväntade fel från operativsystemet. Returnera alltid ett konsekvent resultat-/felpar så att anropande kod kan hantera misslyckanden på ett bra sätt.
local function safeRead(path)
local ok, result = pcall(function()
local f = assert(io.open(path, "r"))
local content = f:read("a")
f:close()
return content
end)
if ok then return result
else return nil, result
end
end
local data, err = safeRead("config.txt")
if data then print("Read", #data, "bytes")
else print("Error:", err)
endFörsöksmönster med pcall
Försök utföra en instabil operation (nätverksförfrågan, filskrivning) upp till N gånger och använd pcall för att fånga fel. Vänta mellan försöken i verklig kod (eller använd coroutines).
local function retry(fn, maxAttempts)
local attempts = 0
while attempts < maxAttempts do
attempts = attempts + 1
local ok, result = pcall(fn)
if ok then
print("Succeeded on attempt", attempts)
return result
end
print("Attempt", attempts, "failed:", result)
end
error("all " .. maxAttempts .. " attempts failed")
end
local n = 0
retry(function()
n = n + 1
if n < 3 then error("not ready") end
return "done"
end, 5)Samla pcall-resultat i en tabell
När pcall används i en loop kan ni spara resultaten i en tabell för senare analys. Detta är användbart vid batchåtgärder där ni vill behandla alla objekt och samla in fel i stället för att avbryta vid det första misslyckandet.
local jobs = {10, -5, 25, 0, 16}
local results = {}
for _, n in ipairs(jobs) do
local ok, v = pcall(function()
if n < 0 then error("negative") end
return math.sqrt(n)
end)
results[#results+1] = {input=n, ok=ok, value=v}
end
for _, r in ipairs(results) do
if r.ok then
print(r.input, "->", string.format("%.3f", r.value))
else
print(r.input, "-> ERROR:", r.value)
end
endpcall jämfört med xpcall
pcall fångar felet men ger er endast felvärdet. xpcall låter er ange en meddelandehanterarfunktion som körs medan stacken fortfarande är intakt, vilket möjliggör stackspårningar. Välj xpcall när ni behöver traceback-information.
-- pcall: simple, no traceback
local ok1, err1 = pcall(function()
error("simple error")
end)
print(err1) -- only the error message
-- xpcall: with traceback handler
local ok2, err2 = xpcall(
function() error("traced error") end,
function(e) return debug.traceback(e, 2) end
)
print(err2) -- full stack tracepcalls returkonvention
Använd pcall som grund för ett konsekvent API: returnera alltid value vid lyckat resultat eller nil, errorMessage vid fel. Bygg era funktioner på detta sätt så att anropande kod alltid vet vad den kan förvänta sig.
local function loadJSON(path)
local ok, result = pcall(function()
local f = assert(io.open(path, "r"))
local text = f:read("a")
f:close()
-- Fake JSON parse for demo
return {data = text, path = path}
end)
if ok then return result
else return nil, result
end
end
local data, err = loadJSON("data.json")
if data then print("Loaded:", data.path)
else print("Failed:", err)
endSnabbkontroll
Vad returnerar pcall när den skyddade funktionen lyckas?
Sammanfattning: pcall
Sammanfattning:
pcall(f, ...)→true, results...ellerfalse, err- Kontrollera det första returvärdet för att avgöra om anropet lyckades eller misslyckades
- Vid lyckat resultat kommer flera returvärden efter true
- Kapslad pcall: varje anrop fångar sina egna fel oberoende av de andra
- Försöksmönster: använd en loop med pcall för instabila operationer
- Använd xpcall när ni behöver stackspårningar
Lär dig Lua med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 40
- Lektioner
- 159
Vanliga frågor
Är lektionen ”Skyddade anrop med pcall” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Lua Academy, inklusive ”Skyddade anrop med pcall”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Lua Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”Skyddade anrop med pcall”?
Fånga fel säkert med pcall och tolka returvärdena. Ni övar på Lua Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Lua Academy?
Du behöver inga förkunskaper. Utbildningen i Lua Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Skyddade anrop med pcall”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Lua Academy-lektionen?
Ja. Varje Lua Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Funktionen error()
- Skyddade anrop med pcall
- xpcall och meddelandehanterare
- Strukturerade felobjekt