Esplorare i tipi riferimento
Quando si scrivono contratti, è necessario comprendere anche i tipi riferimento.
A differenza dei tipi valore, che passano sempre una copia indipendente del valore, i tipi riferimento forniscono una posizione dei dati per il valore. I tre tipi riferimento sono: struct, matrici e mapping.
Ubicazione dei dati
Quando si usa un tipo riferimento, è necessario specificare in modo esplicito la posizione di archiviazione dei dati per il tipo. Per specificare la posizione dei dati in cui è archiviato il tipo, è possibile usare le opzioni seguenti:
memory
:- Posizione in cui sono archiviati gli argomenti della funzione
- Ha una durata limitata alla durata di una chiamata di funzione esterna
storage
:- Posizione in cui sono archiviate le variabili di stato
- Ha una durata limitata alla durata del contratto
calldata
:- Posizione in cui sono archiviati gli argomenti della funzione
- Questa posizione è obbligatoria per i parametri delle funzioni esterne, ma può essere usata anche per altre variabili
- Ha una durata limitata alla durata di una chiamata di funzione esterna
I tipi riferimento creano sempre una copia indipendente dei dati.
Ecco un esempio di come usare un tipo riferimento:
contract C {
uint[] x;
// the data location of values is memory
function buy(uint[] memory values) public {
x = values; // copies array to storage
uint[] storage y = x; //data location of y is storage
g(x); // calls g, handing over reference to x
h(x); // calls h, and creates a temporary copy in memory
}
function g(uint[] storage) internal pure {}
function h(uint[] memory) public pure {}
}
Matrici
Le matrici consentono di archiviare dati simili in una struttura di dati definita. Le matrici possono avere una dimensione fissa o dinamica. Gli indici iniziano da 0.
Per creare una matrice con dimensione fissa k
e tipo di elemento T
, scrivere T[k]
. Per una matrice con dimensione dinamica, scrivere T[]
.
Gli elementi di una matrice possono essere di qualsiasi tipo. Le matrici possono ad esempio contenere elementi uint, memory o byte. Le matrici possono anche includere mapping o struct.
Gli esempi seguenti mostrano la creazione di una matrice:
uint[] itemIds; // Declare a dynamically sized array called itemIds
uint[3] prices = [1, 2, 3]; // initialize a fixed size array called prices, with prices 1, 2, and 3
uint[] prices = [1, 2, 3]; // same as above
Membri della matrice
I membri seguenti consentono di modificare le matrici e di ottenere informazioni su di esse:
- length: ottiene la lunghezza di una matrice.
- push(): accoda un elemento alla fine di una matrice.
- pop: rimuove un elemento alla fine di una matrice.
Di seguito sono riportati alcuni esempi:
// Create a dynamic byte array
bytes32[] itemNames;
itemNames.push(bytes32("computer")); // adds "computer" to the array
itemNames.length; // 1
Struct
Gli struct sono tipi personalizzati che un utente può definire per rappresentare oggetti reali. Gli struct vengono in genere usati come schema o per rappresentare record.
Esempio di una dichiarazione di struttura:
struct Items_Schema {
uint256 _id;
uint256 _price;
string _name;
string _description;
}
Tipi mapping
I mapping sono coppie chiave-valore incapsulate o inserite in un pacchetto. I mapping sono più simili a dizionari o a oggetti in JavaScript. In genere si usano i mapping per modellare oggetti reali ed eseguire ricerche di dati più velocemente. I valori possono includere tipi complessi come struct, il che rende il tipo di mapping flessibile e leggibile dall'uomo.
L'esempio di codice seguente usa lo struct Items_Schema
e salva un elenco di elementi rappresentati da Items_Schema
come dizionario. In questo modo, il mapping simula un database.
contract Items {
uint256 item_id = 0;
mapping(uint256 => Items_Schema) public items;
struct Items_Schema {
uint256 _id:
uint256 _price:
string _name;
}
function listItem(uint256 memory _price, string memory _name) public {
items[item_id] = Items_Schema(item_id, _price, _name);
item_id += 1;
}
}
Nota
La firma del mapping uint256 => Items_Schema
indica che le chiavi sono un tipo intero senza segno e i valori sono un tipo di struct Items_Schema
.