Lokální a globální proměnné
Od lekce o proměnných píšete local před každou proměnnou a slíbili jsme, že vysvětlíme proč. Teď, když píšete funkce, nastal ten čas.
Každá lokální proměnná má obor platnosti (anglicky scope): část programu, ve které existuje. Začíná na řádku, kde proměnná vznikne, a končí s blokem, ve kterém vznikla: s tělem funkce, podmínky if nebo cyklu, případně s celým programem. Parametry jsou lokální proměnné své funkce. Proměnná vytvořená uvnitř funkce tedy mimo ni neexistuje:
local function spocitejVejce()
local vejce = 12
print("Ve stodole: " .. vejce)
end
spocitejVejce()
print(vejce)Vypíše:
Ve stodole: 12
nilMimo funkci žádné vejce není, takže poslední řádek vypíše nil. Každé volání funkce vytvoří její lokální proměnné znovu a po skončení funkce zaniknou. To je užitečné: dvě funkce můžou mít každá svou proměnnou celkem a nikdy si nepřekážejí.
Opačně to ale jde: funkce vidí lokální proměnné vytvořené nad ní, mimo funkci, a dokonce je může měnit:
local mince = 10
local function kupSemena(cena)
mince = mince - cena
end
kupSemena(3)
kupSemena(2)
print(mince)Vypíše:
5A co proměnná bez local? mince = 50 vytvoří globální proměnnou. Globální proměnná nepatří žádnému bloku: od chvíle, kdy vznikne, existuje všude, v každé funkci, až do konce programu. Globální proměnné jsou i print, math a table, které patří k Lua, a proto je můžete používat kdekoli. Když Lua nenajde lokální proměnnou daného názvu, hledá globální, a když neexistuje ani ta, je hodnota nil. Proto volání funkce před její definicí skončilo chybou attempt to call a nil value (global 'ranniPrace').
Globální proměnné vypadají šikovně, ale způsobují chyby, které se špatně hledají:
- Překlep vytvoří novou proměnnou. Protože proměnná může vzniknout i bez
local, Lua nepozná překlep od nové proměnné.mnice = mince + 5není chyba: Lua potichu vytvoří globální proměnnoumniceamincese nezmění. - Změnit je může cokoli. Globální proměnnou může změnit kterákoli funkce kdekoli v programu, a když má špatnou hodnotu, musíte prohledat celý program. Přepsat jde i
print: poprint = 5skončí každéprint(…)chybouattempt to call a number value (global 'print').
Nejhorší je zapomenuté local uvnitř funkce:
local function prodejVejce(vejce)
mince = vejce * 2
return mince
end
mince = 50
local vydelek = prodejVejce(10)
print("Výdělek: " .. vydelek)
print("Mince: " .. mince)Vypíše:
Výdělek: 20
Mince: 20Ema měla 50 mincí a po prodeji vajec má 20? Funkce chtěla vlastní proměnnou, jenže bez local je mince uvnitř funkce stejná globální proměnná jako venku, a funkce ji přepsala. S local mince = vejce * 2 ve funkci by to byly dvě různé proměnné a Ema by o své mince nepřišla.
Proto tento kurz píše local před každou proměnnou i funkci (function prodejVejce bez local vytvoří globální funkci). Každá proměnná pak existuje jen tam, kde je potřeba, a žádná funkce nezmění omylem proměnné jiné funkce. Hodnoty se do funkce dostávají přes parametry a ven pomocí return. Navíc Lua najde lokální proměnné rychleji než globální. Jen nezapomeňte, že obor platnosti začíná na řádku s local: funkce může používat jen lokální proměnné a lokální funkce vytvořené nad ní.
Jak psát:
Pokyny
Eminy slepice snášely každý den, ale program vypíše Vajec za týden: 0. Ve funkci spocitejVejce je překlep v názvu proměnné. Lua ho neohlásila, jen potichu vytvořila globální proměnnou. Najděte překlep a opravte ho. Program pak vypíše Vajec za týden: 49.
Teď program vypíše Výdělek: 98 mincí a Mince: 196. Ema ale měla 50 mincí, takže by jich měla mít 148. Proměnná mince ve funkci prodejVejce nemá local, a tak funkce přepíše Eminy mince ze začátku programu. Opravte funkci, aby používala vlastní lokální proměnnou. Program pak vypíše:
Vajec za týden: 49
Výdělek: 98 mincí
Mince: 148Samotná funkce prodejVejce je pořád globální. Udělejte z ní lokální funkci, stejně jako je spocitejVejce. Program vypíše totéž.
Začněte programovat zdarma
6/11