Kontakty

Úvod do Lua. Chcete vedieť všetko. Lua Language Learning lua od nuly

Môj blízky priateľ išiel nedávno na pracovný pohovor do miestnej spoločnosti na vývoj hier. Nebudem tu menovať mená, len povedzte, že to bol akýsi veľký butik s vývojom hier vo Vancouveri. Nezískal prácu, ale dnes o ňom nehovoríme. Osobne sa domnievam, že jedným z dôvodov bol nedostatok priateľských vzťahov so skriptovacím jazykom, ktorý používajú.

Úvod

Som v tejto oblasti, keďže učím študentov programovanie hier, no práve tejto téme som v minulosti nevenoval dostatočnú pozornosť. Unreal Script pokrývame v rámci kurzu Using Existing. Skriptovací modul sme však v skutočnosti nepovažovali za súčasť nástrojov alebo za súčasť motora. Takže, vyzbrojený webovou stránkou, som sa rozhodol prelomiť túto malú bariéru. Výsledok je popísaný v tomto dokumente.

Jediná vec, nie som si istý, aký veľký tento dokument bude. Môžem ho rozložiť na niekoľko malých častí alebo zverejniť celý v dlhej tiráde od začiatku do konca. Každopádne sa o tom rozhodnem o niečo neskôr, keď svoje poznámky vložím do zmysluplnejšieho a konzistentnejšieho formátu.

Prečo a prečo nie?

Po prvé, prečo používať skriptovací jazyk? Väčšina hernej logiky môže byť napísaná v skriptovacom jazyku na rôzne účely, namiesto toho, aby bola naprogramovaná ako súčasť herného enginu. Napríklad načítanie alebo inicializácia úrovne. Po načítaní úrovne možno budete chcieť preložiť scénu do herného plánu, alebo možno budete chcieť ukázať nejaký predbežný text. Pomocou skriptovacieho systému môžete prinútiť určité objekty v hre vykonávať špecifické úlohy. Zvážte aj implementáciu umelej inteligencie. Nehrateľné postavy musia vedieť, čo majú robiť. Programovanie každého NPC „ručne“ v tele herného enginu zbytočne skomplikuje úlohu. Ak chcete zmeniť správanie NPC, budete musieť svoj projekt prekompilovať. Pomocou skriptovacieho systému to môžete urobiť interaktívne zmenou správania a uložením nastavení.

Tohto problému som sa trochu dotkol v poslednom odseku, o tom si povieme trochu neskôr. Otázkou je, prečo nepísať logiku výlučne v C / C ++? Zjednodušene povedané, programátor má z dlhodobého hľadiska to, že všetko padá priamo na neho a začína, resp. z kódu hry, zároveň bude musieť napísať engine a utility atď. Teraz však môžeme niektoré úlohy funkcií preniesť na dizajnérov úrovní pomocou jednoduchého skriptovacieho jazyka. Môžu sa začať hrabať v leveli a optimalizovať hrateľnosť. Tu je príklad:

Predstavme si, že Joe, náš nešťastný programátor, píše celý herný engine, nástroje a hernú logiku sám. Áno, Joe bude mať problémy, ale predpokladajme, že mu je to jedno. Máme tiež Brandona, herného dizajnéra. Brandon je celkom šikovný chlapec so skvelými nápadmi na hru. A tak náš kodér Joe vyliezol a implementoval všetku hernú logiku pomocou súpravy nástrojov, ktorú vyvinul na základe Brandonovho počiatočného projektu. V kancelárii je všetko v poriadku. Prvá fáza sa skončila a Joe a Brandon sedia v zasadacej miestnosti a prehodnocujú svoju značnú prácu. Brandon si všimne niekoľko problémov s hrateľnosťou, ktorá sa nespráva správne. Joe sa teda vráti ku kódu a vykoná požadované zmeny. Tento proces môže trvať deň, aspoň ak nejde o triviálnu zmenu. Potom ďalší deň na prekompilovanie projektu. Aby nestratili ani deň navyše, väčšina kancelárií opúšťa montážny proces zo dňa na deň. Takže, ako vidíme, trvá 24 hodín, kým Brandon uvidí zmenu, ktorú požadoval.

Teraz predstierajme, že náš hlavný hrdina Joe sa rozhodol, že implementácia hernej logiky využíva skriptovací stroj vo svoj prospech. Zo začiatku to bude nejaký čas trvať, ale cíti, že z dlhodobého hľadiska to bude prospešné. A tak presúva niektoré funkcie z herného enginu do systému skriptov hry. V už spomínanom skriptovacom systéme píše aj všetku hernú logiku. A tak, keď stretne Brandona a dizajnér si všimne niečo, čo nezodpovedá jeho predstave, Joe rýchlo otvorí konzolu, urobí nejaké zmeny v scenári, reštartuje hru a už vidí nové správanie. Zmeny je možné vykonať okamžite a okamžite ich zobraziť, namiesto čakania na opätovnú kompiláciu. A ak by bol Joe obzvlášť výrazný, skriptovací systém by mohol byť použitý pre pomocné programy a dostupný pre dizajnérov úrovní pri budovaní úrovní. Ak pôjdete touto cestou, potom s trochou tréningu môžu dizajnéri úrovní sami nastaviť herné udalosti, ako sú spúšťače, dvere, iné herné udalosti a užívať si život bez toho, aby napínali programátora.

Toto je dosť vymyslený príklad a môže byť trochu prehnaný, ale dúfam, že ukazuje rozdiel medzi prístupmi. Takže to, čo sa snažíme urobiť s týmto modelom, čo znamená prejsť na viac automaticky spravovaných údajov. Takže v podstate kam ideme:

  1. Kódera zaujíma písanie kódu motora/nástrojov, nie logiky hry.
  2. Čas strávený písaním herného enginu / nástrojov.
  3. Dizajnéri sa radi s vecami hrajú. Skriptovanie im dáva slobodu pri navrhovaní úrovní a funkčnosti. Tiež im to dáva väčšiu flexibilitu pri experimentovaní s vecami, na ktoré by normálne zapájali programátora.
  4. Ak chcete zmeniť funkčnosť hry, nemusíte ju znova kompilovať. Stačí zmeniť scenár.
  5. Chcete prerušiť spojenie medzi strojom a kódom hry. Mali by byť rozdelené do dvoch samostatných častí. Takto bude vhodné využiť engine pre budúce pokračovania (dúfam).

Tu urobím niekoľko predpovedí. Počas nasledujúcich 5 rokov budú musieť dizajnéri úrovní urobiť viac než len stavať úrovne. Musia vedieť používať scenár herných scén. Tento prístup už zvolilo niekoľko špičkových spoločností. Túto integračnú metódu môžete vidieť aj v editoroch ako UnrealEd a Aurora toolset Bioware.

Objasnenie a vychvaľovanie

Dúfam, že teraz ste už pochopili moje slová a chceli ste do svojej hry zahrnúť skript. Ďalšia otázka teda znie: ako to do pekla robíte?

Čo budem používať pre môj skriptový komponent, je injektovateľný skriptovací stroj Lua... Na začiatok poviem, že nie som odborník na Lua, ale je to pomerne jednoduchý jazyk a na jeho zvládnutie nie je potrebné zdĺhavé učenie. Niektoré z príkladov, ktoré prejdem neskôr, sú celkom jednoduché. Na konci tohto dokumentu uvediem niekoľko ďalších referenčných materiálov. Aby sme boli spravodliví, existujú aj iné skriptovacie jazyky ako Small, Simkin, Python, Perl. Lua je však pekný a čistý jazyk. To je naozaj dobrá výhoda.

Lua je open source. Je to dobré, pretože: (a) Získate zdroj jazyka a môžete kopať, koľko chcete, (b) je to zadarmo. Môžete ho použiť v komerčných aplikáciách bez vyhadzovania peňazí. No pre nekomerčné projekty ty sám rozumieš zadarmo == dobre.

Kto teda momentálne používa Lua? Lua je napísaná kanceláriou Sharashka a používajú ju iba chudobní? Mmm... vlastne nie. Lua sa včera neobjavila a používali ju známe osobnosti:

  • Lucasarts
    • Ponuré fandango
    • Útek z Opičieho ostrova
  • Bioware
    • Nikdy zimné noci

Ok, dosť s tým, kto je kto z vývojárov lua. Môžete sa o tom presvedčiť na webovej stránke lua.

Začnime naozaj jednoducho. Prvá vec, ktorú musíme postaviť, nám ukáže, ako sa používa tlmočník lua. Čo je k tomu potrebné:

  1. Získanie kódu tlmočníka Lua.
  2. Nastavenie vášho vývojového prostredia.
  3. Budovanie tlmočníka od nuly.

Hej, myslel som, že si povedal dosť žartovania?

Je to dosť? Poďme teda na vec. Celý zdrojový kód Lua môžete získať z oficiálnej webovej stránky. Tiež by som chcel chvíľu poukázať na to, že na obzore je nová verzia lua 5.0. V tomto článku nebudem rozoberať túto verziu. Budem sa tým zaoberať neskôr, ale zatiaľ budeme používať 4.0.1.

Prvá vec, ktorú urobíme, je vybudovať knižnicu lua. Nemusíme teda uvádzať zdroje zakaždým, keď staviame projekt. Nie je to ťažké a nie je to cieľom našich lekcií. Knižnicu som preto v predstihu zaradil do tohto článku. Pre tento príklad som použil statickú knižnicu. Áno, možno by som to postavil ako DLL, ale pre skriptovací systém je statická knižnica o niečo rýchlejšia. Všimnite si, nie oveľa, ale rýchlejšie.

Náš dnešný hosť je skutočným bojovníkom skrytého frontu. Možno ste ho videli v hrách (World of Warcraft, Angry Birds, X-Plane, S.T.A.L.K.E.R.) či produktoch Adobe (Lightroom), no o jeho existencii ste nikdy ani len neuvažovali. Medzitým má tento jazyk už takmer 25 rokov a celý ten čas nenápadne zlepšil náš virtuálny život.

Rýchla referencia

Lua by bola vytvorená v roku 1993 Katolíckou univerzitou v Rio de Janeiro. Názov je preložený z portugalčiny ako Luna a tvorcovia presvedčivo žiadajú nepísať LUA, aby, nedajbože, niekto nepovažoval názov za skratku. Je to multiparadigmový skriptovací jazyk využívajúci model prototypu OOP.

Písanie je tu dynamické a metatabuľky sa používajú na implementáciu dedičnosti, to znamená, že je to skvelý nástroj na rozšírenie možností vášho produktu. Navyše je vďaka svojej kompaktnosti vhodný na použitie na takmer každej platforme. Posúďte sami: tarball Lua 5.3.4 váži iba 296 kilobajtov (nekomprimovaný - 1,1 megabajtov), ​​interpret (napísaný v C) pre Linux - od 182 do 246 kilobajtov a štandardná sada knižníc - ďalších 421 kilobajtov.

Kód

Vzhľadom a schopnosťami vyzerá Lua ako ďalší pokus o prerobenie JavaScriptu, nebyť toho, že ten sa objavil o dva roky neskôr. Presvedčte sa sami:

Začnime tým tradičným:

vytlačiť ("Ahoj svet")

Súhlasím, známe a nie príliš informatívne. Zaujímavejší príklad z hľadiska znalosti Lua je výpočet faktoriálu zadaného čísla:

Funkčný fakt (n)
ak n == 0, potom
vrátiť 1
inak
návrat n * fakt (n-1)
koniec
koniec

Vytlačiť ("zadajte číslo:")
a = io.read ("* číslo") - prečítať číslo
vytlačiť (fakt (a))

Všetko je veľmi jasné. Mimochodom, Lua podporuje paralelné priradenie:

A na záver celkom jednoduchý príklad s použitím knižníc:

#include
#include
#include
#include
#include

Int main (void) (
char buff;
int chyba;
lua_State * L = lua_open (); / * otvára Lua * /
luaopen_base (L); / * otvorí základnú knižnicu * /
luaopen_table (L); / * otvorí knižnicu tabuliek * /
luaopen_io (L); / * otvorí I/O knižnicu * /
luaopen_string (L); / * otvorí reťazec lib. * /
luaopen_math (L); / * otvorí matematickú knižnicu. * /

Kým (fgets (buff, sizeof (buff), stdin)! = NULL) (
chyba = luaL_loadbuffer (L, buff, strlen (buff), "riadok") ||
lua_pcall (L, 0, 0, 0);
ak (chyba) (
fprintf (stderr, "% s", lua_tostring (L, -1));
lua_pop (L, 1); / * vyskočí chybová správa zo zásobníka * /
}
}

Lua_close (L);
návrat 0;
}

Výhody a nevýhody

Čo je teda na Lue dobré?

Po prvé, ako už bolo uvedené, vďaka svojej kompaktnosti a v spojení so skutočnosťou, že zdrojový kód je napísaný v jazyku C, získate plnú interakciu s jedným z najpopulárnejších jazykov na planéte a širokou škálou dostupných platforiem.

Vývojové prostredia

LDT (Lua Development Tools) pre Eclipse - rozšírenie pre jedno z najpopulárnejších IDE;

ZeroBrane Studio je špecializované prostredie napísané v jazyku Lua;

Decoda nie je najpopulárnejším multiplatformovým IDE, ale bude fungovať ako alternatíva;

SciTE je dobrý editor s plnou podporou Lua;

WoWUIDesigner - hádajte, ktorej hre toto prostredie pomáha pri spracovaní skriptov, vrátane Lua?

užitočné odkazy

http://www.lua.org/home.html - oficiálna stránka so všetkými potrebnými informáciami, návodmi, knihami, dokumentáciou a dokonca aj špecifickým humorom;

http://tylerneylon.com/a/learn-lua/ je skvelý návod od Tylera Neylona. Vhodné pre skúsených programátorov, ktorí vedia dobre po anglicky (ale ani so slovníkom nebudú veľké problémy) a chcú si len rozšíriť obzory;

https://zserge.wordpress.com/2012/02/23/lua- for-60-minutes/ - Základy Lua za 60 minút od programátora, ktorému tento jazyk zjavne nie je ľahostajný. V ruštine;

http://lua-users.org/wiki/LuaTutorial - wiki návod

https://youtube.com/watch?v=yI41OL0-DWM- videonávody na YouTube, ktoré vám pomôžu vizuálne pochopiť nastavenie IDE a základné princípy jazyka.

Lua skripty

Skript napísaný v jazyku Lua nemá žiadnu špeciálnu funkciu, z ktorej by sa spúšťal jeho výkon. Skript si možno jednoducho predstaviť ako súbor príkazov (inštrukcií), ktoré sa vykonávajú od prvej inštrukcie.

Skript môže byť buď veľmi jednoduchý, pozostávajúci iba z jedného príkazu, alebo veľmi zložitý, obsahujúci desiatky, stovky alebo dokonca tisíce inštrukcií. Po sebe idúce inštrukcie môžu byť oddelené bodkočiarkou (;). Táto požiadavka je však voliteľná, takže celý nižšie uvedený kód je syntakticky správny:

Práca s premennými v Lua

Premenné sa používajú na ukladanie hodnôt počas vykonávania skriptu.

Názvy premenných v jazyku Lua

Názvy premenných (identifikátory) v Lua môžu byť ľubovoľné poradie písmen, číslic a podčiarkovníkov, ktoré nezačínajú číslom.

Poznámka

Lua rozlišuje veľké a malé písmená, takže abc, Abc, ABC sú rôzne názvy.

V tabuľke nižšie sú uvedené slová, ktoré sú vyhradené jazykom Lua a nemožno ich použiť v názvoch premenných:

a prerušte to inak

koniec nepravda pre funkciu if

v miestnom nula nie resp

repeat return potom true do

Okrem toho sú vyhradené aj všetky názvy začínajúce podčiarkovníkom, za ktorým nasledujú veľké písmená (napríklad _VERSION).

Aké premenné sú v Lua?

Premenné v Lua môžu byť globálne alebo lokálne. Ak premenná nie je explicitne deklarovaná ako lokálna, považuje sa za globálnu.

Lua globálne premenné

Globálna premenná sa objaví, keď je k nej priradená prvá hodnota. Pred priradením prvej hodnoty má volanie globálnej premennej hodnotu nula.

MsgBox (tostring (g)) -> nula

MsgBox (tostring (g)) -> 1

Globálna premenná existuje, pokiaľ existuje prostredie vykonávania skriptu a je dostupná pre akýkoľvek kód Lua spustený v tomto prostredí.

Ak je to potrebné, môžete explicitne odstrániť globálnu premennú jednoduchým priradením nulovej hodnoty.

g = 1 - vytvorte globálnu premennú g s hodnotou 1

g = nula - vymaže globálnu premennú g

MsgBox (tostring (g)) -> nula

Všetky globálne premenné sú poliami bežnej tabuľky nazývanej globálne prostredie. Táto tabuľka je prístupná prostredníctvom globálnej premennej _G. Keďže polia globálneho prostredia sú všetky globálne premenné (vrátane samotného _G), potom _G._G == _G.

Lokálne premenné Lua

Všetky lokálne premenné musia byť deklarované explicitne pomocou kľúčového slova local. Lokálnu premennú môžete deklarovať kdekoľvek v skripte. Deklarácia môže zahŕňať priradenie počiatočnej hodnoty premennej. Ak nie je priradená žiadna hodnota, premenná obsahuje nulu.

local a - deklaruje lokálnu premennú a

lokálna b = 1 - deklarujte lokálnu premennú b, priraďte jej hodnotu 1

lokálne c, d = 2, 3 - deklarujte lokálne premenné c a d, priraďte im hodnoty 2 a 3

Rozsah lokálnej premennej začína po deklarácii a pokračuje do konca bloku.

Poznámka

Rozsah premennej je časť programového kódu, v rámci ktorej máte prístup k hodnote uloženej v danej premennej.

Blok znamená:

telo riadiacej štruktúry (if-then, else, for, while, repeat);

funkčné telo;

kus kódu priložený v kľúčových slovách do ... end.

Ak je lokálna premenná definovaná mimo akéhokoľvek bloku, jej rozsah siaha až na koniec skriptu.

lokálne i = 1 - premenná i je v rámci skriptu lokálna

kým<= a do - цикл от 1 до 5

local a = i ^ 2 - premenná a je lokálna v rámci cyklu while

MsgBox (a) -> 1, 4, 9, 16, 25

MsgBox (a) ->

ak i> 5 potom

lokálne a - premenná a je vo vnútri lokálna

MsgBox (a) -> 10

MsgBox (a) -> 5 (tu odkaz na globálne a)

local a = 20 - premenná a je lokálna vo vnútri do-end

MsgBox (a) -> 20

MsgBox (a) -> 5 (tu odkaz na globálne a)

Poznámka

Vždy, keď je to možné, sa odporúča použiť lokálne premenné namiesto globálnych. Vyhnete sa tak „zahlteniu“ globálneho menného priestoru a poskytnete lepší výkon (keďže prístup k lokálnym premenným v Lua je o niečo rýchlejší ako globálny).

Typy údajov Lua

Aké typy údajov podporuje Lua?

Lua podporuje nasledujúce typy údajov:

1. Nil (nič). Zodpovedá tomu, že premenná nemá žiadnu hodnotu. Tento typ je reprezentovaný jedinou hodnotou, nula.

2. Boolean (logický). Tento typ zahŕňa hodnoty false a true.

Pri vykonávaní logických operácií sa nula považuje za nepravdivú. Všetky ostatné hodnoty vrátane čísla 0 a prázdneho reťazca sa považujú za pravdivé.

3. Číslo (numerické). Slúži na reprezentáciu číselných hodnôt.

Číselné konštanty môžu obsahovať voliteľnú zlomkovú časť a voliteľné desatinné poradie špecifikované znakmi „e“ alebo „E“. Celočíselné číselné konštanty možno zadať v hexadecimálnej sústave pomocou predpony 0x.

Príklady platných číselných konštánt: 3, 3,0, 3,1415926, 314,16e-2, 0xff.

4. String (šnúrka). Slúži na reprezentáciu reťazcov.

Hodnoty reťazca sú špecifikované ako postupnosť znakov, uzavretá v jednoduchých alebo dvojitých úvodzovkách:

a = "toto je reťazec"

b = "toto je druhý riadok"

Reťazce v úvodzovkách môžu interpretovať sekvencie typu escape (escape sekvencie), ktoré začínajú znakom „\“ (obrátená lomka):

\ b (medzera),

\ n (riadkový posuv),

\ r (návrat vozíka);

\ t (horizontálna karta),

\\ (obrátená lomka);

\ "" (dvojité úvodzovky);

\ "(jediná úvodzovka).

Poznámka

Znak v reťazci môže byť reprezentovaný aj vlastným kódom pomocou sekvencie escape:

kde ddd je postupnosť maximálne troch číslic.

Okrem úvodzoviek možno na definovanie reťazca použiť aj dvojité hranaté zátvorky:

Definovanie reťazca s dvojitými hranatými zátvorkami umožňuje ignorovať všetky únikové sekvencie, t. j. reťazec sa vytvorí presne podľa popisu:

miestne a = [] v Lua] =]

Bude existovať výraz: "definícia reťazca [] v Lua"

5. Funkcia. Funkcie v Lua môžu byť zapísané do premenných, odovzdané ako parametre iným funkciám a vrátené ako výsledok vykonania funkcií.

6. Tabuľka. Tabuľka je množina párov kľúč – hodnota, ktoré sa nazývajú polia alebo prvky tabuľky. Kľúče aj hodnoty polí v tabuľke môžu byť akéhokoľvek typu okrem nuly. Tabuľky nemajú pevnú veľkosť: môžete do nich kedykoľvek pridať ľubovoľný počet prvkov.

Viac podrobností - v článku "Vytváranie tabuliek v Lua"

7. Údaje používateľa (údaje používateľa). Ide o špeciálny dátový typ. Hodnoty tohto typu nemožno vytvárať ani upravovať priamo v skripte Lua.

Používateľské údaje sa používajú na reprezentáciu nových typov vytvorených v programe volania skriptov alebo v knižniciach napísaných v jazyku C. Napríklad knižnice rozšírenia Lua pre „CronosPRO“ používajú tento typ na reprezentáciu objektov, ako sú:

dátové banky (trieda Banka);

databázy (základná trieda);

záznamy (trieda Záznam) atď.

8. Niť (niť). Zodpovedá toku vykonávania. Tieto streamy nie sú žiadnym spôsobom spojené s operačným systémom a sú podporované výlučne prostredníctvom samotnej Lua.

Ako nastaviť typ premennej v Lua?

Lua explicitne nenastavuje typ premennej. Typ premennej je nastavený v čase, keď je premennej priradená hodnota. Každej premennej je možné priradiť hodnotu akéhokoľvek typu (bez ohľadu na to, aký typ hodnoty predtým obsahovala).

a = 123 - premenná a je typu číslo

a = "123" - premenná a je teraz typu string

a = true - teraz je premenná a typu boolean

a = () - teraz je premenná a typu tabuľka

Poznámka

Premenné typu tabuľka, funkcia, vlákno a používateľské údaje neobsahujú samotné údaje, ale ukladajú odkazy na zodpovedajúce objekty. Pri priraďovaní, prechode do funkcie ako argumentu a následnom návrate z funkcie sa objekty neskopírujú, skopírujú sa iba odkazy na ne.

a = () - vytvorte tabuľku. Odkaz na tabuľku je umiestnený v premennej a

b = a - premenná b sa vzťahuje na rovnakú tabuľku ako a

a = 10 - prvok tabuľky s indexom 1 má priradenú hodnotu 10

MsgBox (b) -> "10"

MsgBox (a) -> "20"

Ostatné údaje sú okamžité hodnoty.

MsgBox (a) -> "20"

MsgBox (b) -> "10"

Ako získať typ premennej v Lua?

Typ hodnoty uloženej v premennej je možné zistiť pomocou štandardného typu funkcie. Táto funkcia vracia reťazec obsahujúci názov typu ("nula", "číslo", "reťazec", "boolean", "tabuľka", "funkcia", "vlákno", "userdata").

t = typ ("toto je reťazec") - t sa rovná "reťazec"

t = typ (123) - t sa rovná "číslu"

t = typ (typ) - t je "funkcia"

t = typ (pravda) - t je "booleovské"

t = typ (nula) - t je "nulová"

t = typ (CroApp.GetBank ()) - t sa rovná "userdata"

Ako previesť typ premennej v Lua?

Lua podľa potreby automaticky prevádza čísla na reťazce a naopak. Ak je napríklad hodnota reťazca operandom v aritmetickej operácii, skonvertuje sa na číslo. Podobne aj číselná hodnota, ktorá sa vyskytuje tam, kde sa očakáva reťazec, sa skonvertuje na reťazec.

a = "10" + 2 - a sa rovná 12

a = "10" + 2 - a sa rovná "10 + 2"

a = "-5,3e-10" * "2" - a sa rovná -1,06e-09

a = "reťazec" + 2 - Chyba! Nie je možné previesť "reťazec" na číslo

Akákoľvek hodnota môže byť explicitne prevedená na reťazec pomocou štandardnej funkcie tostring.

a = tostring (10) - a sa rovná "10"

a = tostring (pravda) - a rovná sa "pravda"

a = tostring (nula) - a rovná sa "nula"

a = tostring ((= "toto je pole 1")) - a sa rovná "tabuľka: 06DB1058"

Z predchádzajúceho príkladu môžete vidieť, že obsah tabuliek nie je konvertovaný funkciou tostring. Túto transformáciu je možné vykonať pomocou funkcie render.

a = render (10) - a sa rovná "10"

a = render (pravda) - a rovná sa "pravda"

a = render (nula) - a rovná sa "nula"

a = render ((= "toto je pole 1")) - a sa rovná "(=" toto je pole 1 ")"

Na explicitný prevod hodnoty na číslo môžete použiť štandardnú funkciu tonumber. Ak je hodnotou reťazec, ktorý je možné previesť na číslo (alebo je už číslom), funkcia vráti výsledok prevodu, inak vráti nulu.

a = tonumber ("10") - a rovná sa "10"

a = tonumber ("10" .. ". 5") - a sa rovná 10,5

a = tonumber (pravda) - a je "nulové"

a = tonumber (nula) - a je "nula"

Usporiadanie komentárov v Lua

Komentár v Lua začína dvoma znamienkami mínus (-) a pokračuje až do konca riadku.

local a = 1 - jednoriadkový komentár

Ak za znakmi „-“ bezprostredne nasledujú dve otvorené hranaté zátvorky ([[)], komentár je viacriadkový a pokračuje až do dvoch uzatváracích hranatých zátvoriek (]]).

lokálne a = 1 - [[viacriadok

komentár ]]

Dvojité zátvorky v komentároch môžu byť vnorené. Aby nedošlo k ich zámene, medzi zátvorky sa vkladá znamienko rovnosti (=):

miestne a = [[Kronos Company]] - [= [

miestne a = [[Kronos Company]]

Počet symbolov "=" určuje vnorenie:

local a = [= [definícia nejakého reťazca [] v jazyku Lua] =] - [== [

local a = [= [definícia nejakého reťazca [] v jazyku Lua] =]

Operácie Lua

Vo výrazoch napísaných v jazyku Lua možno použiť nasledujúce typy operácií:

1. Aritmetické operácie.

Lua podporuje nasledujúce aritmetické operácie:

+ (sčítanie);

- (odčítanie);

* (násobenie);

/ (oddelenie);

^ (umocnenie);

% (zvyšok delenia).

Poznámka

Aritmetické operácie sa vzťahujú na čísla aj reťazce, ktoré sa v tomto prípade prevedú na čísla.

2. Operácie porovnávania.

V jazyku Lua sú povolené nasledujúce porovnávacie operácie:

== (rovná sa);

~ = (nerovná sa);

< (меньше);

> (viac);

<= (меньше или равно);

> = (väčšie alebo rovnaké).

Poznámka

Porovnávacie operácie vždy vrátia boolovskú hodnotu true alebo false.

Pravidlá pre prevod čísel na reťazce (a naopak) nefungujú pri porovnávaní, to znamená, že výraz "0" == 0 má za následok nepravdu.

3. Logické operácie.

Logické operácie zahŕňajú:

a (logické AND).

Operátor and vráti svoj prvý operand, ak je nepravdivý alebo nulový. V opačnom prípade operácia vráti druhý operand (navyše tento operand môže byť akéhokoľvek typu).

a = (nula a 5) - a je nula

a == (nepravda a 5) - a rovná sa nepravda

a == (4 a 5) - a sa rovná 5

alebo (logické ALEBO).

Operátor alebo vráti prvý operand, ak nie je nepravdivý alebo nulový, inak vráti druhý operand.

a == (4 alebo 5) - a sa rovná 4

a == (nepravda alebo 5) - a sa rovná 5

Poznámka

Booleovské operácie a alebo môžu vrátiť hodnoty akéhokoľvek typu.

Logické operátory a alebo vyhodnotia hodnotu druhého operandu iba v prípade, že je potrebné ho vrátiť. Ak sa nevyžaduje, druhý operand sa nevyhodnocuje. Napríklad:

a == (4 alebo f ()) - funkcia f () sa nezavolá

nie (logické NIE).

Operácia nie vždy vráti hodnotu true alebo false.

4. Činnosť zreťazenia.

Na zreťazenie (spojenie) reťazcov použite operáciu ... (dve bodky).

a = "Kronos" .. "-" .. "Informovať" - premenná a dostane hodnotu "Kronos-Inform"

Poznámka

Ak jeden alebo oba operandy sú čísla, skonvertujú sa na reťazce.

a = 0..1 - premenná a dostane hodnotu "01"

5. Operácia získania dĺžky.

Lua definuje operátor dĺžky #, ktorý možno použiť na získanie dĺžky reťazca.

a = "reťazec"

len = #a - dĺžka je 6

len = # "ďalší riadok" - dĺžka je 10

Poznámka

Na zistenie maximálneho indexu (alebo veľkosti) poľa môžete použiť aj operáciu #. Viac podrobností - v článku "Práca s poľami v Lua".

Priorita operácie v Lua

V Lua sa operácie vykonávajú podľa nasledujúcej priority (v zostupnom poradí):

2.nie # - (unárne)

6. < > <= >= ~= ==

Volanie skriptov z formulárov

Každý formulár (vrátane vnorených formulárov) má priradený samostatný skript, ktorý zvyčajne obsahuje funkcie, ktoré spracovávajú udalosti formulára a jeho prvkov.

Po spustení formulára sa jeho skript načíta do globálneho prostredia. Keď nastane udalosť formulára alebo jeho prvku, systém zavolá funkciu handlera priradenú k tejto udalosti.

Treba poznamenať, že formulárový skript, hoci neobsahuje volanie funkcie modulu, je v skutočnosti modul. To znamená, že premenné deklarované vo formulárovom skripte bez lokálneho kľúčového slova sa nepresúvajú do globálneho prostredia a sú dostupné iba v rámci tohto skriptu. Ak potrebujete sprístupniť hodnotu pre skripty iných foriem, musí byť explicitne definovaná v globálnej tabuľke _G:

miestne a = _G.var

Bloky výpisov

Hlavnými operátormi Lua sú:

zadanie;

podmienený operátor;

operátorov na organizovanie slučiek.

Skupinu príkazov je možné spojiť do bloku (zložený príkaz) pomocou konštrukcie do… end.

do - začiatok bloku

<оператор1>- blokové telo

<оператор2>

<операторN>

koniec - koniec bloku

Blok otvára nový rozsah, v ktorom môžete definovať lokálne premenné.

a = 5 - globálna premenná a

local a = 20 - vnútri do-end lokálna premenná a je definovaná

MsgBox (a) -> 20

MsgBox (a) -> 5 (tu je volanie už na globálne a)

Operátor priradenia Lua

Priradenie mení hodnotu premennej alebo poľa tabuľky. V najjednoduchšej forme môže úloha vyzerať takto:

a = 1 - premennej a je priradená hodnota 1

a = b + c - premennej a je priradený súčet hodnôt premenných b a c

a = f (x) - premennej a je priradená hodnota vrátená funkciou f (x)

Lua umožňuje takzvané viacnásobné priradenie, keď niekoľko premenných naľavo od operátora priradenia dostane hodnoty niekoľkých výrazov zapísaných napravo od operátora priradenia:

a, b = 1,5 * c - a sa rovná 1; b sa rovná 5 * c

Ak je premenných viac ako hodnôt, premenným „navyše“ sa priradí nula.

a, b, c = 1, 2 - a je 1; b je 2; c je nula

Ak existuje viac hodnôt ako premenných, "extra" hodnoty sa ignorujú.

a, b = 1, 2, 3 - a je 1; b je 2; hodnota 3 sa nepoužíva

Viacnásobné priradenie je možné použiť na výmenu hodnôt medzi premennými:

a = 10; b = 20 - a je 10, b je 20

a, b = b, a - teraz a je 20, b je 10

Podmienečné vyhlásenie (ak) v jazyku Lua

Príkaz if testuje, či je zadaná podmienka pravdivá. Ak je podmienka pravdivá, vykoná sa časť kódu, ktorá nasleduje za kľúčovým slovom then (časť potom). V opačnom prípade sa vykoná kód nasledujúci za kľúčovým slovom else (časť else).

ak a> b potom

návrat a - ak je a väčšie ako b, vráti a

návrat b - v opačnom prípade návrat b

Časť else je voliteľná.

Ak< 0 then

a = 0 – ak je a menšie ako 0, nastavte a na 0

Namiesto vnorených príkazov if môžete použiť konštrukt elseif. Napríklad nasledujúci kód:

bude ľahšie porozumieť, ak ho nahradíte nasledujúcim:

návrat "Ivan" - ak a je 1

elseif a == 2 potom

návrat "Peter" - ak a je 2

elseif a == 3 potom

návrat "Sergey" - ak a je 3

return "Neexistuje taký hráč" - ak a nie je nič z vyššie uvedeného

Lua while slučka

Príkaz while je navrhnutý tak, aby organizoval slučky s podmienkou a má nasledujúci tvar:

zatiaľ čo robiť

... - telo cyklu

Pred každou iteráciou cyklu sa kontroluje podmienka :

ak je podmienka nepravdivá, cyklus sa skončí a riadenie sa prenesie do prvého príkazu nasledujúceho po príkaze while;

ak je podmienka pravdivá, vykoná sa telo cyklu, po ktorom sa všetky akcie zopakujú.

zatiaľ čo i> 0 do - slučka od 10 do 1

t [i] = "pole" ..i

a = (3, 5, 8, -6, 5)

pričom i> 0 do - hľadanie zápornej hodnoty v poli

ak [i]< 0 then break end - если найдено, прерываем цикл

i = i - 1 - inak prejdite na ďalší prvok

ak i> 0 potom

MsgBox ("Index zápornej hodnoty:" ..i)

MsgBox ("Pole neobsahuje záporné hodnoty")

Poznámka

Slučka s dodatočnou podmienkou (opakovanie) v Lua

Príkaz repeat je navrhnutý tak, aby organizoval slučky s postcondition a má nasledujúci tvar:

... - telo cyklu

kým

Telo cyklu sa vykonáva tak dlho ako podmienka sa nestane pravdou. Podmienka sa kontroluje po vykonaní tela slučky, preto sa telo slučky v každom prípade vykoná aspoň raz.

Sčítajte hodnoty poľa a, kým súčet nepresiahne 10

a = (3, 2, 5, 7, 9)

súčet = súčet + a [i]

do súčtu> 10

MsgBox ("Naskladané" ..i .. "položky. Suma je" ..súčet)

Príkaz break môžete použiť na ukončenie cyklu pred jeho dokončením.

Poznámka

Viac podrobností o funkciách používania operátora break - v článku "Príkazy break a return"

Lua for slučky

Príkaz for je určený na organizovanie slučiek a môže byť napísaný v dvoch formách:

jednoduché (číselné pre);

predĺžený (univerzálny pre).

Jednoduchý tvar príkazu for

Jednoduchý tvar príkazu for vyzerá takto:

pre var = exp1, exp2, exp3 do

... - telo cyklu

Telo cyklu sa vykoná pre každú hodnotu premennej cyklu (počítadla) var v rozsahu od exp1 do exp2 s krokom exp3.

Poznámka

Krok nemusí byť nastavený. V tomto prípade sa rovná 1.

pre i = 1, 10 do - slučka od 1 do 10 s krokom 1

MsgBox ("i sa rovná" ..i)

pre i = 10, 1, -1 do - slučka od 10 do 1 s krokom -1

MsgBox ("i sa rovná" ..i)

Poznámka

Výrazy exp1, exp2 a exp3 sa vyhodnocujú iba raz, pred začiatkom cyklu. Takže v nižšie uvedenom príklade sa funkcia f (x) zavolá na výpočet hornej hranice cyklu iba raz:

pre i = 1, f (x) do - cyklus od 1 do hodnoty vrátenej funkciou f ()

MsgBox ("i sa rovná" ..i)

Premenná cyklu je lokálna pre príkaz cyklu a na jeho konci nie je definovaná.

pre i = 1, 10 do - cyklus od 1 do hodnoty vrátenej f ()

MsgBox ("i sa rovná" ..i)

MsgBox ("Po opustení slučky sa i rovná" ..i) - Chyba! som nula

Poznámka

Hodnotu premennej slučky nie je možné zmeniť vo vnútri slučky: dôsledky takejto zmeny sú nepredvídateľné.

Ak chcete cyklus ukončiť pred jeho dokončením, použite príkaz break.

a = (3, 5, 8, -6, 5)

pre i = 1, # a do - hľadajte zápornú hodnotu v poli

ak [i]< 0 then - если найдено...

index = i - uloženie indexu nájdenej hodnoty ...

zlomiť - a zlomiť slučku

MsgBox ("Index zápornej hodnoty:" ..index)

Poznámka

Viac podrobností o funkciách používania operátora break - v článku "Príkazy break a return")

Som sentimentálny programátor. Niekedy sa do programovacích jazykov zamilujem a potom o nich dokážem rozprávať hodiny. Podelím sa s vami o jednu z týchto hodín.

Lua? Čo je toto?

Lua je jednoduchý vložiteľný jazyk (môže byť integrovaný s vašimi programami napísanými v iných jazykoch), ľahký a jednoduchý, s jedným typom údajov a jednotnou syntaxou. Perfektný jazyk na učenie.

Za čo?

Lua by sa vám mohla hodiť:

* ak ste hráč (pluginy pre World of Warcraft a mnoho ďalších hier)
* ak píšete hry (veľmi často v hrách je engine napísaný v C / C ++ a AI - v Lua)
* ak ste systémový programátor (môžete písať pluginy pre nmap, wireshark, nginx a ďalšie nástroje v Lua)
* ak ste embedded vývojár (Lua je veľmi rýchly, kompaktný a vyžaduje veľmi málo zdrojov)

1. Naučte sa programovať. Aspoň trochu. Je jedno v akom jazyku.
2. Nainštalujte Lua. Ak to chcete urobiť, stiahnite si verziu 5.2 tu (http://www.lua.org/download.html), alebo ju vyhľadajte v úložiskách. Verzia 5.1 bude fungovať tiež, ale uvedomte si, že je veľmi stará.

Spustite všetky príklady z článku v termináli pomocou príkazu ako „lua file.lua“.

Prvé dojmy

Lua je dynamicky typovaný jazyk (premenné získavajú typy „za behu“ v závislosti od priradených hodnôt). Môžete do nej písať imperatívom aj objektovo orientovaným či funkčným štýlom (aj keď neviete ako, nevadí, čítajte ďalej). Tu je Hello world v Lua:

Moja prvá lua aplikácia: hello.lua print "hello world"; tlač ("zbohom svet")

Čo už možno povedať o jazyku:

* jednoriadkové komentáre začínajú dvoma pomlčkami "-"
* zátvorky a bodkočiarky možno vynechať

Jazykoví operátori

Sada podmienok a slučiek je celkom typická:

Podmienené príkazy (nemusia existovať žiadne iné vetvy) ak a == 0, potom vypíšte („a je nula“), inak vypíšte („a nie je nula“) koniec - skrátená forma if / elseif / end (namiesto prepínača / prípadu) ak a == 0, potom vytlačte ("nula") elseif a == 1 potom vytlačte ("jeden") elseif a == 2 potom vytlačte ("dva") else vytlačte ("iný") koniec - slučka počítadla pre i = 1, 10 do print (i) koniec - slučka s predbežnou podmienkou b = 5, zatiaľ čo b> 0 do b = b - 1 koniec - slučka s dodatočnou podmienkou opakovanie b = b + 1, kým b> = 5

THINK: čo by mohla znamenať slučka „pre i = 1, 10, 2 do ... koniec“?

Vo výrazoch môžete pre premenné použiť nasledujúce operátory:

* priradenie: x = 0
* aritmetika: +, -, *, /,% (zvyšok delenia), ^ (umocnenie)
* boolean: a, alebo, nie
* porovnanie:>,<, ==, <=, >=, ~ = (nerovná sa, áno-áno, namiesto obvyklého "! =")
* zreťazenie reťazcov (operátor ".."), napríklad: s1 = "ahoj"; s2 = "svet"; s3 = s1..s2
* dĺžka / veľkosť (operátor #): s = "ahoj"; a = #s („a“ bude 5).
* získanie prvku podľa indexu, napr.: s

Dlho v jazyku neexistovali bitové operácie, no vo verzii 5.2 sa objavila knižnica bit32, ktorá ich implementuje (ako funkcie, nie ako operátory).

Typy údajov

Klamal som vám, keď som povedal, že jazyk má jeden typ údajov. Má ich veľa (ako každý seriózny jazyk):

* nula (vôbec nič)
* boolovské čísla (pravda / nepravda)
* čísla (čísla) - žiadne delenie celými číslami / reálne. Len čísla.
* struny – mimochodom sú veľmi podobné strunám v pascale
* funkcie - áno, premenná môže byť typu "funkcia".
* vlákno
* ľubovoľné údaje (údaje používateľa)
* stôl

Ak je pri prvých typoch všetko jasné, čo sú potom používateľské údaje? Pamätajte, že Lua je vložený jazyk a zvyčajne úzko spolupracuje s komponentmi programov napísaných v iných jazykoch. Takže tieto "cudzie" komponenty môžu vytvárať dáta podľa svojich potrieb a ukladať tieto dáta spolu s lua objektmi. Užívateľské dáta sú teda podvodná časť ľadovca, ktorá z pohľadu jazyka lua nie je potrebná, no jednoducho ju nemôžeme ignorovať.

A teraz najdôležitejšia vec v jazyku sú tabuľky.

Tabuľky

Znova som ti klamal, keď som povedal, že jazyk má 8 dátových typov. Môžete predpokladať, že je jeden: všetko sú tabuľky (mimochodom, to tiež nie je pravda). Tabuľka je veľmi elegantná dátová štruktúra, spája vlastnosti poľa, hašovacej tabuľky ("kľúč" - "hodnota"), štruktúry, objektu.

Takže tu je príklad tabuľky ako poľa: a = (1, 2, 3) - pole 3 prvkov vytlačí (a) - vypíše "2", pretože indexy sa počítajú od jedného - Tabuľka je riedke pole (ktoré nemá všetky prvky) a = () - prázdna tabuľka a = 1 a = 5

THINK: Čo je to pre riedke pole?

Vo vyššie uvedenom príklade sa tabuľka správa ako pole, ale v skutočnosti máme kľúče (indexy) a hodnoty (prvky poľa). A zároveň môžu byť kľúče akéhokoľvek typu, nielen čísla:

A = () a ["ahoj"] = pravda a ["svet"] = nepravda a = 1 - alebo takto: a = (ahoj = 123, svet = 456) tlač (a ["ahoj")) tlač ( a.hello) je to isté ako ["ahoj"], hoci vyzerá ako štruktúra s poľami

Mimochodom, keďže tabuľka obsahuje kľúče a hodnoty, môžete prechádzať cez všetky kľúče a ich zodpovedajúce hodnoty v slučke:

T = (a = 3, b = 4) pre kľúč, hodnota v pároch (t) vytlačiť (kľúč, hodnota) - vypíše "a 3", potom "b 4" koniec

Ale čo predmety? Najprv sa o nich dozvieme o niečo neskôr - o funkciách.

Funkcie

Tu je príklad bežnej funkcie.

Funkcia add (a, b) return a + b end print (add (5, 3)) - vytlačí "8"

Jazykové funkcie vám umožňujú vziať viacero argumentov a vrátiť viacero argumentov. Napríklad argumenty, ktoré nie sú explicitne špecifikované, sa považujú za nulové.

THINK: Prečo by ste chceli vrátiť viacero argumentov?

Funkcia swap (a, b) return b, a end x, y = swap (x, y) - mimochodom, dá sa to urobiť aj bez funkcie: x, y = y, x - a ak funkcia vráti viacero argumentov , - a nepotrebujete ich - ignorujte ich pomocou - špeciálna premenná podčiarknutia "_" a, _, _, d = nejaká_funkcia ()

Funkcie môžu mať premenlivý počet argumentov:

V prototype je premenný počet argumentov zapísaný ako elipsa funkcia suma (...) s = 0 pre _, n v pároch (arg) do - vo funkcii sú označované ako tabuľka "arg" s = s + n end vráti konečný súčet (1, 2, 3) - vráti 6 súčet (1, 2, 3, 4) - vráti 10

Keďže funkcie sú plnohodnotným dátovým typom, môžete vytvárať premenné funkcií alebo môžete funkcie odovzdávať ako argumenty iným funkciám.

A = funkcia (x) return x * 2 end - funkcia, ktorá sa vynásobí 2 b = funkcia (x) return x + 1 end - funkcia, ktorá sa zvýši o 1 funkcia platí (tabuľka, f) výsledok = () pre k, v v páry (tabuľka) urob výsledok [k] = f (v) - prvok nahraď nejakou funkciou z tohto prvku end end - MYSLITE: to, čo volá t = (1, 3, 5) vráti použiť (t, a) použiť ( t, b)

Objekty = funkcie + tabuľky

Keďže funkcie môžeme ukladať do premenných, môžeme aj do polí tabuliek. A to sa už ukazuje ako metódy. Pre tých, ktorí OOP nepoznajú, poviem, že jeho hlavným prínosom (aspoň v Lua) je, že funkcie a dáta, s ktorými pracujú, sú vedľa seba – v rámci toho istého objektu. Pre tých, ktorí poznajú OOP, poviem, že tu neexistujú žiadne triedy, ale dedičnosť je prototypová.

Prejdime na príklady. Máme predmet, povedzme, žiarovku. Vie, ako zapáliť a nespáliť. No, existujú dve akcie, ktoré s tým môžete urobiť - zapnúť a vypnúť:

Lamp = (on = false) function turn_on (l) l.on = true end function turn_off (l) l.on = false end sú len funkcie na prácu so štruktúrou turn_on (lampa) turn_off (lampa)

A ak zmeníme žiarovku na objekt a zmeníme funkcie turn_off a turn_on na polia objektu, dostaneme:

Lampa = (on = falošné zapnutie = funkcia (l) l.on = skutočný koniec turn_off = funkcia (l) l.on = falošný koniec) lampa.zapnutie (lampa) lampa.turn_off (lampa)

Ako prvý argument sme nútení odovzdať samotný objekt žiarovky, pretože inak naša funkcia nebude vedieť, s ktorou žiarovkou potrebuje pracovať, aby zmenila stav zapnutia / vypnutia. Ale aby to nebolo veľavravné, Lua má zvyčajne používanú skratku - lampa: turn_on (). Celkovo už poznáme niekoľko takýchto zjednodušení syntaxe:

Lamp: turn_on () - najbežnejší zápis lamp.turn_on (lamp) - z hľadiska syntaxe je to tiež správne lampa ["turn_on"] (lampa) - a toto

Pokračujúc v rozprávaní o skratkách, funkcie možno opísať nielen explicitne ako polia štruktúry, ale aj vo vhodnejšej forme:

Lampa = (on = nepravda) - cez bodku, potom musí byť argument špecifikovaný funkcia lampa.turn_on (l) l.on = true end - cez dvojbodky, potom je argument implicitne nastavený ako premenná "self" - "self " - a tam je lampa, pre ktorú bola funkčná lampa nazývaná: turn_off () self.on = falošný koniec

zaujímavé?

Špeciálne funkcie

Niektoré názvy tabuľkových funkcií (metód) sú vyhradené a majú osobitný význam:

* __add (a, b), __sub (a, b), __div (a, b), __mul (a, b), __mod (a, b), __pow (a, b) – volá sa, keď sa vykonávajú aritmetické operácie tabuľky
* __unm (a) - unárna mínusová operácia (keď píšu niečo ako "x = -x")
* __lt (a, b), __le (a, b), __eq (a, b) - vypočítajte výsledok porovnania (<, <=, ==)
* __len (a) – volá sa, keď sa vykoná „#a“.
* __concat (a, b) – volá sa, keď „a..b“
* __call (a, ...) – volá sa, keď je „a ()“. Variabilné argumenty sú argumenty pri volaní
* __index (a, i) – volanie [i] za predpokladu, že takýto prvok neexistuje
* __newindex (a, i, v) – vytvorenie „a [i] = v“
* __gc (a) - keď je objekt vyradený zberom odpadu

Nahradením týchto metód môžete preťažiť operátorov a použiť syntax jazyka pre svoje vlastné účely. Hlavná vec je nepreháňať to.

Dedičnosť

Pre tých, ktorí nepoznajú OOP, dedičnosť umožňuje rozšíriť funkčnosť existujúcej triedy. Napríklad len žiarovka sa môže rozsvietiť a zhasnúť a super žiarovka tiež zmení svoju svietivosť. Prečo musíme prepísať metódy turn_on / turn_off, keď ich môžeme znova použiť?

Lua má na to koncept meta tabuľky, t.j. tabuľky predkov. Každá tabuľka má jednu nadradenú tabuľku a podradená tabuľka môže robiť všetko, čo môže robiť rodič.

Povedzme, že sme už vytvorili objekt stola s lampou. Potom bude super žiarovka vyzerať takto:

Superlamp = (jas = 100) - špecifikujte nadradenú tabuľku setmetatable (superlamp, lampa) - a jej metódy sú teraz dostupné superlamp: turn_on () superlamp: turn_off ()

Rozšírenie funkčnosti

Existuje mnoho typov rodičovských tabuliek (no, reťazce a tabuľky, určite čísla a booleovské hodnoty a nula nie). Povedzme, že chceme pridať všetky riadky pomocou operátora „+“, nie „...“. Ak to chcete urobiť, nahraďte funkciu „+“ (__add) pre nadradenú tabuľku všetkých riadkov:

S = getmetatable ("") - získal rodičovskú tabuľku riadku s .__ add = funkcia (s1, s2) return s1..s2 end - zmenil metódu - skontrolujte a = "ahoj" b = "svet" print ( a + b) - napíše "helloworld"

V skutočnosti stále môžeme nahradiť funkciu tlače za "print = moja funkcia" a dá sa urobiť mnoho ďalších vecí, ktoré sa týkajú hackovania.

Rozsahy

Premenné sú globálne a lokálne. Po vytvorení sú všetky premenné v Lua globálne.

MYSLITE: prečo?

Ak chcete určiť lokálny rozsah, napíšte lokálne kľúčové slovo:

Lokálne x lokálne var1, var2 = 5, 3

Nezabudnite na toto slovo.

Chyba pri spracovaní

Často, ak sa vyskytnú chyby, musíte zastaviť vykonávanie konkrétnej funkcie. Môžete samozrejme urobiť veľa kontrol a zavolať „návrat“, ak sa niečo pokazí. To však zvýši množstvo kódu. Lua používa niečo ako výnimky.

Chyby sa vyvolávajú pomocou funkcie error (x). Ako argument je možné odovzdať čokoľvek (čo je relevantné pre chybu – popis reťazca, číselný kód, objekt, s ktorým sa chyba vyskytla atď.)

Väčšinou po tejto funkcii spadne celý program. A to nie je vždy potrebné. Ak zavoláte funkciu, ktorá môže spôsobiť chybu (alebo jej dcérske funkcie môžu spôsobiť chybu), zavolajte ju bezpečne pomocou pcall ():

Funkcia f (x, y) ... ak ... potom chyba ("nepodarilo sa niečo urobiť") koniec ... koncový stav, err = pcall (f, x, y) - f: funkcia, xy: jej argumenty ak nie je stav, potom - zvládnuť chybu err. V našom prípade err obsahuje koniec textu chyby

Štandardné knižnice

Existuje veľa neštandardných knižníc, možno ich nájsť na LuaForge, LuaRocks a ďalších úložiskách.

Medzi Lua a Non-Lua

A ak nám nestačí funkčnosť štandardných knižníc? Čo ak máme svoj program v jazyku C a chceme volať jeho funkcie z Lua? Existuje na to veľmi jednoduchý mechanizmus.

Povedzme, že chceme vytvoriť vlastnú funkciu, ktorá vráti náhodné číslo (Lua má math.random (), ale chceme sa to naučiť). Budeme musieť napísať nasledujúci kód v C:

#include #include #include / * čo vlastne robiť pri volaní `rand (od, do)` * / static int librand_rand (lua_State * L) (int od, do; int x; od = lua_točíslo (L, 1); / * prvý parameter funkcia * / do = lua_tonumber (L, 2); / * druhý parameter funkcie * / x = rand ()% (do - od + 1) + od; lua_pushnumber (L, x); / * návratová hodnota * / návrat 1; / * vráti iba jeden argument * /) / * v Lua "rand" zodpovedá našej funkcii librand_rand () * / static const luaL_reg R = (("rand", librand_rand), (NULL, NULL) / * koniec zoznamu exportovaných funkcií * / ); / * volané pri načítaní knižnice * / LUALIB_API int luaopen_librand (lua_State * L) (luaL_openlib (L, "librand", R, 0); srand (čas (NULL)); návrat 1; / * úspešné * /)

Tie. Lua nám poskytuje funkcie na prácu s dátovými typmi, na prijímanie argumentov funkcií a vracanie výsledkov. Funkcií je málo a sú veľmi vzdialené. Teraz budujeme našu knižnicu ako dynamickú knižnicu a môžeme použiť funkciu rand ():

Náhodné = vyžadovať ("librand") - načítať tlač knižnice (random.rand (1, 100)) tlač (random.rand (0, 1))

Čo ak chceme volať kód Lua z našich programov? Potom by naše programy mali vytvoriť virtuálny stroj Lua, v ktorom sa budú vykonávať skripty Lua. Je to oveľa jednoduchšie:

#include "lua.h" #include "lauxlib.h" int main () (lua_State * L = lua_open (); // vytvorenie virtuálneho stroja Lua luaL_openlibs (L); // načítanie štandardnej knižnice luaL_dofile (L, " rand. lua "); // spustite skript lua_close (L); // zatvorte Lua návrat 0;)

Všetko.

Teraz môžete písať v Lua. Ak zistíte zaujímavé body o Lua, ktoré by sa mohli odraziť v článku - píšte!

Táto séria tutoriálov, ktorú som vytvoril, bude diskutovať o programovacom jazyku Lua. Budem sa snažiť, aby bola prezentácia pre začiatočníkov čo najprístupnejšia a budem sa venovať práve im. To znamená, že skúsení Lua kóderi sa z toho s najväčšou pravdepodobnosťou nedozvedia nič nové (som si istý, že nájdu priestor len na šomranie a poznámky, ktoré sú z ich strany dokonca vítané), ale ak nemáte bohaté skúsenosti s programovaním za vami, potom si myslím, že niečo zvládnete.

Celá séria sa nepodriadi žiadnemu systému. Lekcie postupne predstavia množstvo jazykových konštruktov, takže v tretej alebo štvrtej lekcii už môžete písať svoje programy. Mojím cieľom je dotlačiť vás k tomu, aby ste sa jazyk naučili sami, pomôcť vám ho precítiť a nie vysvetľovať ho od A po Z – ak chcete jazyk úplne ovládať, prečítajte si referenčnú príručku (ktorá je, aj keď zle, preložené do ruštiny: http: //www.lua .ru / doc /). Čím skôr prejdete z lekcií „pre machrov“ na webe k preštudovaniu návodu, tým lepšie.

Ak niečo nie je jasné - určite položte otázku v komentároch a ja a ostatní členovia sa vám pokúsime pomôcť.

Lua je populárny, ľahko naučiteľný, vložiteľný, interpretovaný, dynamicky písaný univerzálny programovací jazyk. Nie, nemusíte rozumieť ani polovici slov v predchádzajúcej vete – hlavné je vedieť, že je populárna a nekomplikovaná. Mimochodom, svoju popularitu si získal vďaka svojej jednoduchosti a malej veľkosti distribučnej súpravy (asi 150 kilobajtov). Skripty Lua podporuje veľké množstvo aplikácií vrátane hier. World of Warcraft a S.T.A.L.K.E.R. používať jazyk Lua. Môj obľúbený herný engine vám umožní ľahko vytvárať rôzne hry pomocou Lua. Ako vidíte, Lua vám otvára veľa obzorov!

Skôr ako začneme, musíte nastaviť programovacie prostredie: to znamená nájsť program, ktorý akceptuje kód Lua, ktorý napíšete, a vykoná ho: interpret. Tu sú tri možnosti:

1. Stiahnite si oficiálnu distribúciu Lua z jednej zo stránok, ktoré ich dodávajú.

Z oficiálnej stránky Lua je možné stiahnuť iba zdrojový kód tlmočníka. Keď si však prečítate http://lua.org/download.html v sekcii Binárne súbory, môžete nájsť odkazy na stránky so spustiteľnými súbormi pre Windows. Jeden z nich: . Stiahnite si odtiaľ jeden z archívov (zodpovedajúci vašej platforme: Win32 alebo Win64) a niekde ho rozbaľte, najlepšie do adresára s krátkou cestou: napríklad C: \ lua. Odteraz budem predpokladať, že používate Windows a váš tlmočník je tam.

Používatelia operačných systémov založených na Linuxe sú v tomto zmysle jednoduchší: stačí im použiť správcu balíkov a nainštalovať Lua z repozitárov. Na Debiane a Ubuntu sa to robí pomocou apt-get install lua a na Fedore, Red Hat a derivátoch sa to robí pomocou yum install lua. Neverte mi však slepo a prečítajte si príručku k vášmu operačnému systému, aby ste zistili, ako presne to robíte.

2. Použite online tlmočníka.

Nachádza sa na http://www.lua.org/demo.html. Spočiatku to môže stačiť, ale neskôr, keď sa dotkneme modulov, budete musieť použiť offline verziu. Používanie online tlmočníka je veľmi jednoduché: do okna s textom zadajte svoj program a kliknite na tlačidlo Spustiť. Program sa spustí, v okne Výstup sa zobrazí výstup vášho programu, ako aj chybové hlásenia, ak nejaké existujú.

3. Použite IDE.

Napríklad ZeroBrane Studio: http://studio.zerobrane.com/. Sú aj iní – hľadajte na internete.

Teraz sú v obehu dve mierne odlišné verzie Lua: 5.1 a 5.2. Zameriam sa na najnovšiu verziu – verziu 5.2, no určite poukážem na dôležité rozdiely medzi ňou a 5.1, keďže tá druhá je tiež celkom bežná. Mimochodom, Lua 5.1 vykonáva kód jeden a pol krát rýchlejšie ako Lua 5.2, takže viete.

=== Lekcia č. 1 ===

Takže začnime. Vytvorte súbor main.lua v priečinku izolovanom od cudzích súborov a napíšte doň:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
- main.lua -
vytlačiť ("Ahoj svet!")

Potom spustite na príkazovom riadku (nezabudnite sa presunúť do adresára s main.lua pomocou príkazu cd):

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
> C: \ lua \ lua.exe main.lua

V reakcii na to tlmočník Lua vydá:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
Ahoj svet!

V zásade sa to dalo očakávať. V programe sme zavolali funkciu tlače. Funkcia tlače preberá ľubovoľný počet parametrov a vytlačí ich postupne na obrazovku. V tomto príklade sme mu odovzdali reťazec (reťazec znakov) "Ahoj svet!" Rovnako dobre môžete odovzdať ako parameter:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
print (8) - nejaké desatinné číslo
- bude výstup: 8

Tlač (0xDEADBEEF) - hexadecimálne číslo
- bude výstup: 3735928559

Print ("0xDEADBEEF") je reťazec, nie číslo! Vidíš tie úvodzovky?
- bude výstup: 0xDEADBEEF

Tlač (1,35e-4) – číslo s pohyblivou rádovou čiarkou (zlomkové číslo)
- Výstup 0,000135. 1,35e-4 treba chápať ako „1,35 vynásobené
- o desať až mínus štvrtý stupeň“, ak niekto nevie.

Tlač ((198 * 99) -3 * 500 + 14/88) - výraz
- Zobrazí hodnotu výrazu: 18102,159090909. Nie je to zlá alternatíva
- stolná kalkulačka!

Tlač (198/7, "hnojivo", 2 ^ 9) - niekoľko parametrov ľubovoľného
- typ. Zobrazia sa hodnoty každého z nich oddelené znamienkami
- karty:
- 28.285714285714 hnojivo 512
- Upozorňujeme, že úvodzovky okolo hnojiva sa nezobrazujú!

Tlač (1,35) sú dve čísla, nie desatinný zlomok 1,35!
- Na oddelenie parametrov sa používa čiarka.
- bude výstup:
-- 1 35

Znak „-“ nie je len imitáciou pomlčky, ktorá sa vkladá pre krásu. Znak "-" v Lua označuje komentáre: rady pre programátora, ktoré interpret ignoruje a ktorých cieľom je uľahčiť pochopenie kódu. Môžete skúsiť napísať do programu:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
- vytlačiť ("nič")

Tlmočník si bude myslieť, že ide o komentár a nebude sa riadiť pokynmi.

Poznámka pre hostesku: ak chcete vytlačiť iba jeden riadok, môžete tlačovú výzvu napísať takto, bez zátvoriek:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
vytlačiť "Iba jeden reťazec"

Pohodlie je určite otázne: len majte na pamäti, že je to možné. Takéto hovory sú však neprijateľné:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
vytlačiť 2 - nebude fungovať, 2 - nie reťazec.
tlač 2 * 2 + 6 - tým viac nebude fungovať

Str = "reťazec!!" - priradil premennej str hodnotu "string !!"
- prečítajte si o premenných nižšie
print str tiež nebude fungovať.

V každom z vyššie uvedených prípadov program jednoducho odmietne pracovať. Pri volaní „bez rodičov“ teda môže za názvom funkcie nasledovať iba reťazcový literál (t. j. sekvencia znakov uzavretá v úvodzovkách) a nič iné. V budúcnosti sa o tejto funkcii porozprávam trochu podrobnejšie, ale zatiaľ vám to stačí.

V každom dobrom programovacom jazyku je možné deklarovať premenné: malé kontajnery, ktoré môžu obsahovať nejaké údaje. Lua to robí takto:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
<имя_переменной> = <выражение>

Napríklad:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
hviezda = 8 - Premenná hviezda teraz ukladá číslo 8
wars = "owl" - premenná wars obsahuje reťazec "owl"
jedi = 42/2 - V premennej jedi - číslo 21
luke = hviezda * jedi - Premenná luke je číslo 168 (áno, 21 krát 8)

Hodnoty premenných a výrazy s nimi môžu byť tiež zobrazené:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
tlač (hviezda, vojny, jedi, hviezda jedi + luke)
- bude výstup:
- 8 sova 21 181

Len sa nepokúšajte pridať premenné hviezda a vojny – pokus o pridanie 8 k „sove“ vám nepomôže!

Ako ste si mali všimnúť, názov premennej môže byť takmer čokoľvek: hlavné je, že nezačína číslom. Vážne, môžete dokonca deklarovať premennú s názvom print a potom funkcia print prestane fungovať, pretože názov print bude odkazovať na novo deklarovanú premennú. Existuje však skupina slov, ktoré je zakázané používať ako názvy premenných – ide o jazykové kľúčové slová, s ktorými sme sa ešte nestretli, no rozhodne stojí za to si ich pozrieť:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
a break do elseif end
false pre funkciu goto if in
lokálne nula nie alebo opakujte návrat
potom pravda až kým

Vytvorením premennej s jedným z týchto názvov spôsobíte chybu v programe a tá určite nebude fungovať. Upozorňujeme, že v Lua 5.1 nie je žiadne kľúčové slovo goto a môžete tak pomenovať premennú, ale radšej to nerobte.
Upozorňujeme tiež, že názvy premenných rozlišujú veľké a malé písmená. To znamená, že foo, fOo, fOO a FOO sú štyri rôzne premenné, takže ak ste názov premennej napísali malými písmenami a neskôr veľkými písmenami, program s najväčšou pravdepodobnosťou nebude fungovať správne.

Teraz jeden dôležitý bod: čo sa stane, ak sa náhodou alebo zámerne odvoláte na neexistujúcu premennú? Vo väčšine ostatných jazykov to spôsobí chybu, ale v Lua je táto situácia prijateľná. Interpretuje sa tak, ako keby neexistujúca premenná skutočne existovala, ale jej hodnota áno nula. nula- zapamätajte si toto slovo! je špeciálny typ hodnoty v jazyku Lua, ktorý znamená „nič“. Nie nula alebo prázdny reťazec (reťazec ako "" - skúste ho zobraziť), ale jednoducho nič. Porovnajte to s týmto modelom: sú dvaja ľudia, jeden z nich má účet v banke, ale nie sú na ňom žiadne peniaze, a druhý nemá žiadny bankový účet. V podmienkach Lua sa bude brať do úvahy, že prvý má na účte 0 dolárov a druhý má nula... A ani nie doláre, ale len tak nula... Dúfam, že som ťa nezmiatol.

Skúste napríklad spustiť takýto program:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
- main.lua -
foo = "bar"
tlačiť (foo, baz)
- bude výstup:
- bar nula

Teda premenná baz, ktorá neexistuje, ale predpokladá sa, že existuje, má hodnotu nula a funkcia print to pochopí a vypíše ju na obrazovku ako reťazec „nil“. Lua má dobrú metódu na kontrolu existencie premennej: ak hodnota premennej nie je nulová, potom je aspoň deklarovaná. Prípadne môžete premennú explicitne deklarovať ako nulovú:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
cool_var = nula

Dá sa to, a hoci sa to na prvý pohľad môže zdať hlúpe, občas sa to podarí. V ďalších lekciách sa dozviete, kto a prečo a pravdepodobne začnete robiť to isté. Niekedy, samozrejme.
Buďte opatrní s nulou: môžete vytlačiť nulu, ale nemôžete s ňou robiť aritmetiku! To znamená, že ak vám prejde tlač (nula), potom konštrukcia ako 99 + nula vyvolá chybu, aj keď by ste chceli 99+ nula sa rovnala 99. Ver mi, aj ja som bol naštvaný, keď som to zistil.

Zhrnutie:
1. Dozvedeli sme sa o funkcii print, čo dokáže a ako ju správne volať bez zátvoriek.
2. Naučil sa deklarovať premenné, počítať výrazy (aj keď dosť málo), aké môžu byť názvy premenných.
3. Dozvedeli sme sa o nule, prenikli jej mystickým tajomstvom a nadobudli istotu, že v budúcnosti nás bude veľa spájať.

Pre tých, ktorí sú zvedaví a chcú si upevniť vedomosti, ponúkam jednoduché cvičenia, ktoré môžete preskočiť, ak sa už cítite dostatočne kompetentní:
1. Napíšte program, ktorý prehrá refrén vašej obľúbenej piesne.
2. Skúste vypísať hodnoty nasledujúcich výrazov. Pokúste sa pochopiť, prečo niektoré z nich fungujú a niektoré nie. Pozrite sa na chyby, ktoré spôsobujú neúspešné výrazy.

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
2 + "reťazec";
6 + "14";
"box" - "vox";
1 * "11b"
"148" * "1e6";


3. Napíšte program, ktorý vymení dve premenné. To je:

200? "200px": "" + (this.scrollHeight + 5) + "px"); ">
a = 6502
b = 8086


Urobte z a rovné 8086 a b rovné 6502. Ak to chcete urobiť, vytvorte tretiu premennú a vykonajte niekoľko jednoduchých swapov. Uistite sa, že je problém vyriešený správne tak, že zavoláte print (a, b) pred výmenou a print (a, b) potom.

Páčil sa vám článok? Zdieľaj to