Korekcijos Lua

A korutine Tai panaši į giją, ji yra vykdymo eilutė su savo krūva, savo vietiniais kintamaisiais ir savo nurodymų rodykle, tačiau ypatinga tuo, kad ji dalijasi visuotiniais kintamaisiais ir bet kokiu kitu elementu su kitomis korutinėmis.

Tačiau turime paaiškinti, kad tarp jų yra skirtumų siūlai ir korutines, pagrindinis skirtumas yra tas, kad programa, kuri naudoja gijas, juos vykdo vienu metu, korutines kita vertus, jie yra bendradarbiaujantys, kai programa, kuri naudoja korutinus, vykdo tik vieną iš jų, o jų sustabdymas pasiekiamas tik tuo atveju, jei to aiškiai prašoma.

The korutines Jie yra nepaprastai galingi, pažiūrėkime, ką ši sąvoka apima ir kaip galime juos panaudoti savo programose.

Pagrindinės sąvokos


Visos funkcijos, susijusios su korutinais Lua yra korutinių lentelėje, kurioje yra funkcija sukurti () leidžia mums juos sukurti, jis turi paprastą argumentą ir yra funkcija su kodu, kurį paleis korutinas, kur jo grąža yra sriegio tipo, reiškiančio naują korutiną, vertė. Net argumentas sukurti korutiną kartais yra anoniminė funkcija, kaip nurodyta šiame pavyzdyje:
 co = coroutine.create (function () print („Hello Solvetic“) pabaiga)
A korutine jis gali turėti keturias skirtingas būsenas:
  • sustabdytas
  • paskubomis
  • miręs
  • normalus

Kai mes jį sukuriame, jis prasideda valstybėje nutrauktas, o tai reiškia, kad pirmą kartą sukurtas korutinas neveikia automatiškai. Su korutino būsena galima susipažinti taip:

 spausdinti (coroutine.status (co))
Kad galėtume paleisti savo korutiną, turime naudoti tik funkciją apibendrina (), tai, ką ji daro viduje, pakeičia savo būseną iš sustabdyto į veikimą.
 coroutine.resume (co)
Jei sujungsime visą savo kodą ir pridėsime papildomą eilutę, norėdami užklausti papildomos mūsų koronaviruso būsenos apibendrina matome visas būsenas, per kurias jis eina:
 co = coroutine.create (function () print ("Hello Solvetic") pabaiga) print (co) print (coroutine.status (co)) coroutine.resume (co) print (coroutine.status (co))
Mes einame į savo terminalą ir paleidžiame savo pavyzdį, pažiūrėkime savo programos išvestį:
 lua coroutines1.lua gija: 0x210d880 Suspended Hello Solvetic dead
Kaip matome, pirmasis įspūdis apie korutiną yra gijos vertė, tada mes turime būseną sustabdytas, ir tai gerai, nes tai yra pirmoji būsena kuriant, tada su apibendrina Paleidžiame korutiną, su kuria jis spausdina pranešimą, o po to jo būsena yra miręskaip įvykdė savo misiją.

„Coroutines“ iš pirmo žvilgsnio gali atrodyti sudėtingas būdas iškviesti funkcijas, tačiau jos yra daug sudėtingesnės. To paties galia priklauso didelei funkcijos daliai išeiga () kuris leidžia sustabdyti vykdomą korutiną, kad vėliau galėtų tęsti jo veikimą, pažiūrėkime šios funkcijos naudojimo pavyzdį:

 co = coroutine.create (function () for i = 1.10 do print ("apibendrinantis coroutine", i) coroutine.yield () pabaigos pabaiga) coroutine.resume (co) coroutine.resume (co) coroutine.resume (co) coroutine .resume (co)
Ši funkcija veiks iki pirmosios derliusir nepriklausomai nuo to, ar turime ciklą dėl, bus spausdinama tik pagal tiek daug apibendrina Paimkime savo korutiną, norėdami baigti, pažiūrėkime išvestį per terminalą:
 lua coroutines 1. lua 1 2 3 4
Tai būtų išėjimas per terminalą.

Filtrai


Vienas aiškiausių pavyzdžių, paaiškinančių korutines, yra atvejis vartotojas Y generatorius informacijos. Tarkime, kad turime funkciją, kuri nuolat generuoja tam tikras reikšmes skaitant failą, o tada turime kitą funkciją, kuri jas skaito, pažiūrėkime, kaip šios funkcijos gali atrodyti:
 funkcijų generatorius (), nors tiesa, daro vietinį x = io.read () siųsti (x) pabaigos pabaigą funkciją vartotojas (), o tiesa - vietinis x = gauti () io.write (x, "\ n") pabaiga
Šiame pavyzdyje tiek vartotojas, tiek generatorius veikia be jokio poilsio, ir mes galime juos sustabdyti, kai nėra daugiau apdorojamos informacijos, tačiau problema yra čia, kaip sinchronizuoti Siųsti () Y gauti (), nes kiekviena iš jų turi savo kilpą, o kita laikoma iškviečiama paslauga.

Tačiau naudojant korupcijas šią problemą galima greitai ir lengvai išspręsti naudojant dvigubą funkciją tęsti / duoti mes galime priversti savo funkcijas veikti be problemų. Kai korutinas iškviečia šią funkciją derlius, ji neįveda naujos funkcijos, bet grąžina laukiantį skambutį, kuris gali išeiti iš tos būsenos tik naudojant atnaujinimą.

Panašiai ir skambinant apibendrina taip pat nepradeda naujos funkcijos, grąžina laukimo skambutį derlius, apibendrinant šį procesą reikia sinchronizuoti funkcijas Siųsti () Y gauti (). Taikydami šią operaciją turėtume pasinaudoti gauti () Taikyti apibendrina prie generatoriaus, kad sugeneruotų naują informaciją ir tada Siųsti () taikyti derlius Vartotojui pažiūrėkime, kaip mūsų funkcijos atrodo su naujais pakeitimais:

 funkcija gauti () vietinė būsena, vertė = korutinas.tęsti (generatorius) grąžinti reikšmę pabaigos funkcija siųsti (x) siųsti (x) pabaiga)
Tačiau mes vis dar galime patobulinti savo programą ir tai padaryti naudodami filtrus, kurios yra užduotys, kurios tuo pat metu veikia kaip generatoriai ir vartotojai, sukurdami labai įdomų informacijos transformacijos procesą.

A filtras gali padaryti apibendrina iš generatoriaus, kad gautumėte naujas vertes ir tada pritaikytumėte derlius pakeisti duomenis vartotojui. Pažiūrėkime, kaip galime lengvai pridėti filtrus prie ankstesnio pavyzdžio:

 genas = generatorius () fil = filtras (genas) vartotojas (fil)
Kaip matome, tai buvo labai paprasta, kai, be savo programos optimizavimo, gavome skaitomumo taškų, svarbių būsimai priežiūrai.

Korekcijos kaip iteratoriai


Vienas ryškiausių generatoriaus / vartotojo pavyzdžių yra iteratoriai esančių rekursiniuose cikluose, kai kartotuvas generuoja informaciją, kurią kūnas sunaudos rekursinio ciklo metu, todėl nebūtų neprotinga naudoti korutinus šiems kartotuvams rašyti, net korutinai turi specialų įrankį šiai užduočiai atlikti.

Norėdami parodyti naudojimą, kurį galime panaudoti korutines, mes parašysime iteratorių, kad sugeneruotume tam tikro masyvo permutacijas, tai yra, kiekvieną masyvo elementą pastatome paskutinėje vietoje ir apverčiame, o po to rekursyviai generuojame visas likusių elementų permacijas. pradinė funkcija būtų be korutinų:

 funkcija print_result (var), kai i = 1, #var do io.write (var [i], "") pabaiga io.write ("\ n") pabaiga
Dabar mes visiškai pakeisime šį procesą, pirmiausia pakeisime print_result () pagal derlių, pažiūrėkime pokytį:
 funkcija permgen (var1, var2) var2 = var2 arba # var1, jei var2 <= 1, tada coroutine.yield (var1) else
Tačiau tai iliustratyvus pavyzdys, parodantis, kaip veikia iteratoriai Lua suteikia mums funkciją, vadinamą apvynioti kuris yra panašus į sukurtiTačiau jis negrąžina korutino, jis grąžina funkciją, kuri, iškvietus, apibendrina korutiną. Tada naudoti apvynioti turėtume naudoti tik šiuos dalykus:
 funkcija permutacijos (var) grąžina coroutine.wrap (funkcija () permgen (var) pabaiga) pabaiga
Paprastai šia funkcija naudotis yra daug lengviau nei sukurti, nes tai suteikia mums tai, ko mums reikia, tai yra apibendrinti, tačiau jis yra mažiau lankstus, nes neleidžia mums patikrinti sukurtos apvynioti.

Korutinos į vidų Lua Jie yra nepaprastai galinga priemonė, padedanti susidoroti su viskuo, kas susiję su procesais, kurie turi būti vykdomi kartu, bet laukiant, kol bus baigtas informacijos teikėjas, taip pat galėtume pamatyti, kaip jie naudojami sudėtingoms generatoriaus / vartotojo procesų problemoms spręsti taip pat optimizuoti iteratorių konstrukciją mūsų programose.

wave wave wave wave wave