Explorer les types référence

Effectué

Pour écrire des contrats, vous devez également comprendre les types référence.

Contrairement aux types valeur, qui passent toujours une copie indépendante de la valeur, les types référence fournissent un emplacement de données à la valeur. Les trois types référence sont les structs, les tableaux et les mappages.

Emplacement des données

Quand vous utilisez un type référence, vous devez fournir explicitement l’emplacement de stockage des données pour le type. Les options suivantes peuvent être utilisées pour spécifier l’emplacement des données où le type est stocké :

  • memory :
    • Emplacement de stockage des arguments de la fonction
    • Durée de vie limitée à la durée de vie d’un appel de fonction externe
  • storage :
    • Emplacement de stockage des variables d’état
    • Durée de vie limitée à celle du contrat
  • calldata :
    • Emplacement de stockage des arguments de la fonction
    • Cet emplacement est obligatoire pour les paramètres des fonctions externes, mais également utilisable pour d’autres variables
    • Durée de vie limitée à la durée de vie d’un appel de fonction externe

Les types référence créent toujours une copie indépendante des données.

Voici un exemple d’utilisation d’un type référence :

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 {}
}

Tableaux

Les tableaux sont un moyen de stocker des données similaires dans une structure de données définie. Les tableaux peuvent avoir une taille fixe ou dynamique. Leurs index commencent à 0.

Pour créer un tableau de taille fixe k et un type d’élément T, vous devez écrire T[k]. Pour un tableau de taille dynamique, vous devez écrire T[].

Les éléments du tableau peuvent être de n’importe quel type. Par exemple, ils peuvent contenir uint, memory ou bytes. Les tableaux peuvent également inclure des mappages ou des structs.

Les exemples suivants montrent la création d’un tableau :

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

Membres de tableau

Les membres suivants peuvent à la fois manipuler et obtenir des informations sur les tableaux :

  • length : Obtenir la longueur d’un tableau.
  • push() : Ajouter un élément à la fin d’un tableau.
  • pop : Supprimer un élément à la fin d’un tableau.

Voici quelques exemples :

// Create a dynamic byte array
bytes32[] itemNames;
itemNames.push(bytes32("computer")); // adds "computer" to the array
itemNames.length; // 1

Structures

Les structs sont des types personnalisés qu’un utilisateur peut définir pour représenter des objets réels. Les structs sont généralement utilisés comme schéma ou pour représenter des enregistrements.

Exemple de déclaration de structure :

struct Items_Schema {
    uint256 _id;
    uint256 _price;
    string _name;
    string _description;
}

Types de mappage

Les mappages sont des paires clé-valeur encapsulées ou empaquetées ensemble. Les mappages s’apparentent aux dictionnaires ou objets en JavaScript. En général, vous utilisez des mappages pour modéliser des objets réels et effectuer des recherches de données plus rapides. Les valeurs peuvent inclure des types complexes comme les structs, ce qui rend le type de mappage flexible et lisible par un humain.

L’exemple de code suivant utilise le struct Items_Schema et enregistre la liste des éléments représentés par Items_Schema sous la forme d’un dictionnaire. Ainsi, le mappage imite une base de données.

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;
    }
}

Notes

La signature du mappage uint256 => Items_Schema indique que les clés sont un type entier non signé et que les valeurs sont un type de struct Items_Schema.