Ссылочные типы
Для написания контрактов вам также потребуется понимать принципы использования ссылочных типов.
В отличие от типов значений, которые всегда передают независимую копию значения, ссылочные типы указывают на расположение данных для значения. Поддерживаются следующие ссылочные типы: структуры, массивы и сопоставления.
Расположение данных
При использовании ссылочного типа необходимо явно указать место хранения данных для него. Расположение данных для типа можно указать следующими способами:
memory
:- Расположение, в котором хранятся аргументы функции.
- Время существования ограничено жизненным циклом вызова внешней функции.
storage
:- Расположение, в котором хранятся переменные состояния.
- Время существования ограничено временем существования контракта.
calldata
:- Расположение, в котором хранятся аргументы функции.
- Это расположение требуется для параметров внешних функций, но может использоваться и для других переменных.
- Время существования ограничено жизненным циклом вызова внешней функции.
Ссылочные типы всегда создают независимую копию данных.
Ниже приведен пример использования ссылочного типа:
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 {}
}
Массивы
Массивы используются для хранения схожих данных в структуре набора данных. Размер массива может быть фиксирован или задаваться динамически. Индекс массива начинаются с 0.
Чтобы создать массив фиксированного размера k
, содержащий элементы типа T
, следует использовать выражение T[k]
. Для массива с динамическим размером можно написать T[]
.
Элементы массива могут иметь любой тип. Например, массив может содержать элементы типа uint, memory или byte. Также массивы могут включать сопоставления или структуры.
В следующем примере показано создание массива:
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
Элементы массива
Для управления массивами и получения сведений о них можно использовать следующие члены:
- length — получение длины массива.
- push() — добавление элемента в конец массива.
- pop — удаление элемента с конца массива.
Ниже приведено несколько примеров:
// Create a dynamic byte array
bytes32[] itemNames;
itemNames.push(bytes32("computer")); // adds "computer" to the array
itemNames.length; // 1
Структуры
Структуры — это настраиваемые типы, с помощью которых пользователь может определять представление реальных объектов. Как правило, структуры используются в качестве схемы или для представления записей.
Пример объявления структуры:
struct Items_Schema {
uint256 _id;
uint256 _price;
string _name;
string _description;
}
Типы сопоставления
Сопоставления представляют собой пары из ключа и значения, которые инкапсулируются или упаковываются вместе. Ближайшими аналогами сопоставлений являются словари или объекты JavaScript. Как правило, сопоставления используются для моделирования реальных объектов и более быстрого поиска данных. В частности, значениями могут быть сложные типы, такие как структуры, обеспечивающие гибкость и удобочитаемость типа сопоставления.
В следующем примере кода используется структура Items_Schema
и сохраняется словарь со списком элементов, представленных структурой Items_Schema
. Таким образом, с помощью сопоставлений можно имитировать базу данных.
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;
}
}
Примечание.
В сигнатуре сопоставления uint256 => Items_Schema
указывается, что ключи имеют целочисленный тип без знака, а значения являются типом структуры Items_Schema
.