Ethereum Solidity: Memory vs. Storage & Ako inicializovať pole vo vnútri struct

V telegrame Loom Network (ktorý má ~ 8 000 členov!) Sa ľudia pýtajú na rôzne témy, ako sú Loomov plán, otázky teoretického blockchainu a Ethereum a riešenie problémov Solidity.

Bola položená konkrétna otázka, ktorá zahŕňala inicializáciu poľa vo vnútri štruktúry. Osoba, ktorá o to požiadala, poskytla svoj kód a pýtala sa, prečo to nefunguje. Nedokázal som vymyslieť odpoveď na temeno hlavy, preto som sa rozhodol krátko o tejto téme hovoriť v príspevku.

Nefunkčný kód nájdete nižšie. Odporúčam vám vyskúšať si riešenie sami (celý čas ste na CryptoZombies cvičili, však?).

Ak chcete nájsť odpoveď, čítajte ďalej.

Je potrebné poznamenať, že vo vyššie uvedenom fiddle je pri deklarovaní premennej miestnosti potrebná pamäť kľúčového slova. Keby bol deklarovaný ako Izba, kompilátor vráti nasledujúcu chybu:

TypeError: Typ struct StructArrayInitWrong.Room memory nie je implicitne konvertibilný na očakávaný typ struct StructArrayInitWrong.Room Ukazovateľ úložiska.

Niektoré teórie

Premenné ukladacieho priestoru zmluvy sú tie, ktoré definujú stav vašej zmluvy a menia sa iba prostredníctvom volaní sendTransaction [1].

premenné pamäte sú dočasné premenné, ktoré existujú iba vo volajúcej funkcii (nemôžu byť deklarované mimo jednej). Po ukončení funkcie sa stierajú a vo všeobecnosti je ich použitie lacnejšie ako premenné v úložisku - viac podrobností o nákladoch na plyn tu.

Pozrime sa na príklad, aby sme pochopili, ako sa dá premenná úložiska použiť vo funkcii, aby ovplyvnila stav zmluvy.

V dolnej časti je kópia x odovzdaná v g (), a tak zostane stavová premenná x po vykonaní nezmenená (preto používame čisté kľúčové slovo.

Na druhej strane y v h () sa deklaruje ako úložisko, čo znamená, že x sa prechádza referenciou. V dôsledku toho sa stavová premenná x zmení po volaní na h ().

Výsledok môžete otestovať volaním f () a následnou kontrolou hodnoty y [2]. Aj keď sa g () volá po h (), nemení hodnotu premennej stavu.

Dostatok teoretizácie, dostaneme sa k odpovedi na pôvodnú otázku.

Keďže pri inicializácii štruktúry nemôžeme inicializovať pole hráčov, sme nútení to urobiť v krokoch:

  1. Inicializujte štruktúru miestnosti na predvolené hodnoty pomocou prázdneho poľa pre hráčov - ako je to opísané tu a v tejto hre.
  2. Zatlačte miestnosť do poľa izieb.
  3. Push msg.sender do poľa hráčov v poslednej miestnosti (rooms.length-1 vždy odkazuje na posledný prvok v poli).

Nižšie nájdete pracovný kód:

Trik je v tom, že nová adresa [] (0) alokuje pamäť pre prázdny súbor adries. Po inicializácii sa miestnosť pridá do miestností a teraz je súčasťou premennej úložiska. To nám umožňuje pracovať s hráčmi na poli a tlačiť na ne hodnoty.

Poznámka: Keby sme urobili nový uint [] (8), dostali by sme rad 8 núl. Môžete si to vyskúšať v tejto hre.

To je dnes všetko, dúfame, že sme odstránili niektoré nedorozumenia týkajúce sa úložiska / pamäte a spôsobu ich použitia vo vašich funkciách. Dajte nám vedieť o svojich otázkach na našom telegramovom kanáli a ak na ne nie je možné odpovedať v niekoľkých správach, venujeme im príspevok (alebo lekciu CryptoZombies!)

Loom Network je platformou blockchain pre vážnych vývojárov dapp - Universal Layer 2, ktorá poskytuje vývojárom nástroje, ktoré potrebujú na vybudovanie funkčných užívateľov orientovaných dapps dnes.

Ste noví na Loom? Začnite tu.

Chcete vložiť svoje žetóny LOOM a pomôcť zabezpečiť Loom Network? Zistite ako.

A ak sa vám tento článok páčil a chcete zostať v slučke, choďte do toho a zaregistrujte sa do nášho súkromného zoznamu adries.