Lua lentukės ir cikliukai

Posted: 2014-11-21 in Pezalai
Žymos:,

Lua | Programavimas | Darau, blėKą gi, šiokie tokie pagrindai apie Lua jau buvo, dabar pakapstysim šiek tiek giliau. Papasakosiu apie Lua lentukes (table), kurios viduje apjungia numeruotus ir asocijuotus masyvus. Taip taip, viena bendra daiktas dviems iš požiūrio skirtingoms struktūroms. Be to, šitos lentukės įgyvendina ir objektinę Lua dalį, bet apie objektizmą bus kitas, atskiras įrašas. Na, o visokiam traversavimui per masyvus ir lentukes, be abejo, reikalingi ciklai, tai čia juos irgi truputėlį užkabinsiu.

Taigi… tiesa, pamiršau pasakyti, kad visi mano sapaliojimai yra apie Lua 5.1 versiją. Nuo 5.0 ir 5.2 ji skiriasi kai kuriais svarbiais niuansais – ciklais ar ten kintamųjų aktyvia erdve.

Lentukės

Lua lentukės yra baisiai jau lanksčios. Iš esmės viskas, kas yra ne paprastas kintamasis, yra arba nil, arba lentukė. Paprasti kintamieji, kaip jau minėjau anąsyk, yra boolean ir numberStringai jau yra… lentukės arba — plačiąja prasme — objektai.

Pirmas daiktas. Tuščia lentukė sukuriama su figūriniais skliausteliais:

> local teibl = {}

Toliau. Lentukė viduje sudaryta iš dviejų dalių: indeksuotos skaičiukais, t.y. masyvinės, dalies ir indeksuotos bet kuo — asociacinės dalies (hash map panašus daiktas yr). Taigi ar jumi reikia paprasto masyvo, ar asocijuoto, ar abiejų viename — naudojate lentukę.

Įsikalam į galvą: Lua masyvai indeksuojami nuo vienetuko! Tiesa, galima ir nulinį indeksą įdėt, bet by default nariai indeksuojami nuo vienetuko. Sakykim, jei sukursim pradinį masyvą su keliom reikšmėm, tai jis bus indeksuotas nuo vienetuko:

> masyvas = { "vienas", "du", "trys" }
> print(masyvas[1])
vienas
> print(masyvas[3])
trys

Dabar niuansėlis. Jei norite sužinoti masyvo dydį, tai naudojamos grotelės ir masyvo pavadinimas:

> print(#masyvas)
3

Taigi, masyve yra trys nariai. Bet čia prasideda Lua durniavimai. Suprantat, grotelės grąžina teisingą narių skaičių tik tada, kai masyve nėra „skylių“. T.y yra visi nariai nuo pirmojo iki kažkelinto. Sakykim, aš masyve sukūriau tris narius — viskas ok, grotelės parodo, kad nariai yra trys. Dabar aš „peršoksiu“ ketvirtą narį, kurio dar nėra ir iš karto priskirsiu penktąjį:

> masyvas[5] = "penki"
> print(#masyvas)
3

Cha, nariai vis tiek tik trys. Nes ketvirto nėra. T.y. grotelės grąžina tik vientisos, be pertrūkių, masyvo dalies apimtį.

O kas, jei masyvas neturi pirmojo nario? Teisingai, atspėjote, toks „masyvas“ narių iš viso „neturi“:

> mas2 = {}
> mas2[2] = "du"
> mas2[3] = "trys"
> print(#mas2)
0

Trumpai tariant, su masyvais reikia elgtis atsargiai. Nežinau, kaip ten tiksliai yra valdoma Lua viduje, bet toks jausmas, kad „skylėti“ masyvai tampa asociaciniais.

Beje, norint papildyti masyvą nebūtina daryti tokios chernios:

mas[#mas+1] = "chernia"

Tam galima pasinaudoti table moduliuku ir padaryti šitaip:

table.insert(mas, "ne chernia!")

Labai norint galima įterpti naują narį ir tam tikroje vietoje:

table.insert(mas, "ne chernia!", 3)

Taip pat galima pašalinti ir paskutinį narį:

table.remove(mas)

Arba norimą:

table.remove(mas, 1)

Asociaciniai masyvai — tai tokie masyvai, kurių „raktai“ yra bet kas. Dažniausiai tai visgi stringai, kurie Lua viduje yra lentukės. Taigi susikurkim pabandymams tuščią lentukę:

> asoc = {}

Dabar žiūrom įdėmiai. Jeigu asociacinio masyvo „raktas“ yra sudarytas iš ASCII raidžių ir skaičių (bet prasideda raide), tai jį galima rašyti prie asociacinio masyvo per taškiuką. Na, trumpai tariant, jei rakto pavadinimas nesipyksta su kintamųjų vardų taisyklėmis, tai naują narį į asociacinį masyvą galima įdėti šitaip:

> asoc.veins = "vienas"

Tai visiškai lygu tokiam parašymui:

> asoc["veins"] = "vienas"

Tiesa, jei jau į raktą įsipainioja kokie nors kitokie simboliai, tai būtina naudoti skliaustelius:

> asoc["1-2"] = -1

Naujas asociacinis masyvas gali būti kuriamas „vietoje“:

> a2 = { veins = "vienas", ["1-2"] = -1 }

Jeigu masyvo kūrimo „erdvėje“ yra kintamasis pavadinimu „vienas“, visiškai laisvai galima daryti ir šitaip:

> a3 = { vienas = vienas }

Vienu ypu galima sukurti mišrią lentukę, t.y. turinčią masyvinę ir asocijuotą dalis:

> mix = { "vienas", "du", "trys", bilekas = "bilekas", ["@home"] = "namai", ["ir t.t."] = "ir taip toliau" }

Be abejo, jos masyvinės dalies narių skaičius bus trys:

> print(#mix)
3

Tiesa, jeigu jau taip iš karto kuriate lentukę su atskiromis masyvo ir asocijuoto masyvo dalimis, tai aš rekomenduočiau dėl kodo gražumo atskirti jas kabliataškiu – jis leidžiamas, kaip alternatyvus skyrybos ženklas:

> mix = { "vienas", "du", "trys"; bilekas = "bilekas", ["@home"] = "namai", ["ir t.t."] = "ir taip toliau" }

Iš asocijuoto masyvo narys pašalinamas jam priskiriant nil:

> mix.bilekas = nil

Tai va, kokios tos lentukės. Bet tai čia tik grožio pradžia. Kaip galbūt jau supratote (o gal dar ir ne), lentukių nariams galima priskirti ir funkcijas. Dar lentukėms galima priskirti jas aprašančias metalentukes. Ir padaryti silpnąsias lentukes. Va tada ir prasideda visokie pseudoobjektai… bet apie tai kada nors, dar pačių funkcijų subtilybių neaprašiau, tad kada nors, kada nors…

Ciklai

Na, kad jau turime lentukių pagrindus, tai dabar galima ir apie ciklus pašnekėti — kaip ten po tas kombinuotas masyvines/asociacines lentukes traversuoti.

Dažniausiai naudojamas ciklas, be abejo, for. Lua neturi atskiro foreach, bet kam jis iš viso reikalingas kai kuriose kalbose – aš nelabai suprantu. Pats paprasčiausias ciklas atrodo šitaip:

for i = 1, 10 do
    print(i)
end

Magiški žodeliai for, do ir end. Priskyrimas paprasts. Beje, „i“ kintamasis automatiškai yra lokalus ir po ciklo jo nerasite. Galima dar pridėti žingsnį:

for i = 1, 10, 2 do
    print(i)
end

 

Jei norėsite perbėgti kokį nors masyvą, tai darysite, be abejo, šitaip:

for i = 1, #mas do
    print(tostring(mas[i]))
end

tostring aš čia šiaip įdėjau, apsidraudimui. Lygiai tą patį galima padaryti su funkcija ipairs, kuri padaro ciklą panašų į foreach:

for i, v in ipairs(mas) do
    print(tostring(v))
end

Kintamasis „i“ įgyja indekso reikšmę, o „v“ – einamojo masyvo nario reikšmę. Kita panaši funkcija yra pairs, kuri „perbėga“ visą lentelę – tiek masyvinę, tiek asocijuotą dalį:

for i, v in pairs(mix) do
    print(i, tostring(v))
end

Kažkas tokio su for ciklais.

Kitas ciklas yra, be abejo, while:

local i = 1
while mas[i] do
    print(mas[i])
    i = i + 1
end

Taaaip… nėra Lua i++ operatoriaus, nėra… o pavyzdiniame cikle išnaudojama ta savybė, kad nesantis masyvo narys yra nil, t.y. prilygsta false.

Beje, labai stebina ir kartais erzina tai, kad Lua nėra continue. Tuo tarpu break yra.

Šiam kartui tiek.

Reklama

Parašykite komentarą

Įveskite savo duomenis žemiau arba prisijunkite per socialinį tinklą:

WordPress.com Logo

Jūs komentuojate naudodamiesi savo WordPress.com paskyra. Atsijungti / Keisti )

Twitter picture

Jūs komentuojate naudodamiesi savo Twitter paskyra. Atsijungti / Keisti )

Facebook photo

Jūs komentuojate naudodamiesi savo Facebook paskyra. Atsijungti / Keisti )

Google+ photo

Jūs komentuojate naudodamiesi savo Google+ paskyra. Atsijungti / Keisti )

Connecting to %s