Lua Academy · Oppitunti

Suojatut kutsut pcall-funktiolla

Siepatkaa virheet turvallisesti pcall-funktiolla ja tulkitkaa paluuarvot.

Oppitunti 2/412 vaihetta

Suojatut kutsut pcall-funktiolla on ilmainen Lua Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu Lua Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Lua Academy-kurssilla on yhteensä 4 oppituntia.

pcall-perusteet

pcall(f, ...) kutsuu funktiota f argumenteilla ... suojatussa tilassa. Jos f onnistuu, pcall palauttaa true-arvon ja sen jälkeen kaikki palautusarvot. Jos f aiheuttaa virheen, pcall palauttaa false-arvon ja sen jälkeen virheviestin. Ohjelman suoritus jatkuu kummassakin tapauksessa.

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: -1

Tiettyjen virheiden käsittely

Tarkistakaa virhearvon tyyppi pcall-kutsun jälkeen, jotta voitte käsitellä erityyppiset virheet eri tavoin. Taulumuotoiset virheet sisältävät rakenteista tietoa, kun taas merkkijonomuotoiset virheet sisältävät viestin. Käsitelkää aina molemmat tapaukset.

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
end

Useat palautusarvot onnistuttaessa

Onnistuneessa suorituksessa pcall palauttaa kaikki suojatun funktion palautusarvot ensimmäisen true-arvon jälkeen. Ottakaa ne talteen useisiin muuttujiin.

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
end

pcall-kutsujen sisäkkäisyys

pcall-kutsut voivat olla sisäkkäisiä. Jokainen pcall luo erillisen suojatun alueen. Sisemmässä pcall-kutsussa tapahtuvan virheen ottaa kiinni sisempi pcall, ei ulompi. Näin voitte toteuttaa varastrategioita.

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 result

pcall ja metodit

Metodin (kaksoispistesyntaksin) kutsumiseksi pcall-funktion kautta välittäkää funktio ja olio ensimmäisenä argumenttina. pcall(obj.method, obj, args...) tai kääritkää kutsu sulkeumaan.

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 divisor

pcall IO-operaatioiden turvallisuuteen

Käärikää IO-operaatiot pcall-kutsuun, jotta voitte ottaa odottamattomat käyttöjärjestelmävirheet kiinni. Palauttakaa yhdenmukainen tulos- ja virhepari, jotta kutsujat voivat käsitellä epäonnistumiset hallitusti.

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)
end

Uudelleenyritysmalli pcall-kutsulla

Yrittäkää epävakaata operaatiota (verkkopyyntöä tai tiedoston kirjoittamista) enintään N kertaa ja käyttäkää pcall-kutsua virheiden kiinniottamiseen. Nukuttakaa ohjelma uudelleenyritysten välillä tuotantokoodissa (tai käyttäkää korutiineja).

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)

pcall-tulosten tallentaminen tauluun

Kun pcall-kutsua käytetään silmukassa, tallentakaa tulokset tauluun myöhempää analyysiä varten. Tämä on hyödyllistä eräoperaatioissa, joissa haluatte käsitellä kaikki kohteet ja kerätä virheet sen sijaan, että suoritus pysähtyisi ensimmäiseen epäonnistumiseen.

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
end

pcall verrattuna xpcall-funktioon

pcall ottaa virheen kiinni, mutta antaa käyttöön vain virhearvon. xpcall-funktion avulla voitte antaa viestinkäsittelijäfunktion, joka suoritetaan kutsupinon ollessa vielä ehjä, jolloin saatte kutsupinon jäljityksen. Valitkaa xpcall, kun tarvitsette kutsupinon jäljityksiä.

-- 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 trace

pcall-palautuskäytäntö

Käyttäkää pcall-kutsua yhdenmukaisen ohjelmointirajapinnan perustana: palauttakaa onnistuttaessa aina value tai epäonnistuttaessa nil, errorMessage. Rakentakaa funktiot tämän periaatteen mukaisesti, jotta kutsujat tietävät aina, mitä odottaa.

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)
end

Pikakertaus

Mitä pcall palauttaa, kun suojattu funktio onnistuu?

Kertaus: pcall

Yhteenveto:

  • pcall(f, ...) → true, results... tai false, err
  • Tarkistakaa ensimmäinen palautusarvo määrittääksenne onnistumisen tai epäonnistumisen
  • Onnistuttaessa true-arvon jälkeen palautetaan useita palautusarvoja
  • Sisäkkäiset pcall-kutsut: jokainen ottaa itsenäisesti kiinni omat virheensä
  • Uudelleenyritysmalli: käyttäkää silmukkaa ja pcall-kutsua epävakaille operaatioille
  • Käyttäkää xpcall-funktiota, kun tarvitsette kutsupinon jäljityksiä
Aloita maksutta

Opi Lua tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
40
Oppitunnit
159

Usein kysytyt kysymykset

Onko oppitunti ”Suojatut kutsut pcall-funktiolla” ilmainen?

Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa Lua Academy-oppimispolun 3 oppituntia, myös oppitunnin “Suojatut kutsut pcall-funktiolla”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Lua Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Suojatut kutsut pcall-funktiolla”?

Siepatkaa virheet turvallisesti pcall-funktiolla ja tulkitkaa paluuarvot. Harjoittelet Lua Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Lua Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Lua Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.

Kuinka kauan ”Suojatut kutsut pcall-funktiolla”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Lua Academy-oppitunnilla?

Kyllä. Jokainen Lua Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. error()-funktio
  2. Suojatut kutsut pcall-funktiolla
  3. xpcall ja viestinkäsittelijät
  4. Rakenteiset virheoliot
← Takaisin: Lua Academy