Зачем использовать массивы, а не сопоставления? [дубликат]

Итак, я выполнял торговый контракт, и мне нужно было вести список продуктов, выставленных на продажу. Я использовал массивы, но позже переключился на сопоставления.

Итак, реализация массивов:

uint[] public productsOnSale;
uint public totalProductsOnSale; 
// array of product to its position
mapping(uint => uint) productToIndex;

в то время как продажа может быть достигнута с использованием

uint public totalProductsOnSale;

mapping(uint => uint) indextoProduct;
mapping(uint => uint) productToIndex;

Поскольку в случае массивов мы отслеживаем значения по любому индексу, мы можем добиться этого и с помощью сопоставления.

Есть ли недостатки использования сопоставлений вместо массива? С точки зрения времени вычислений или с точки зрения стоимости (газа)?

Ответы (2)

Массив стоит больше, чем сопоставление, но это потому, что он не делает то же самое. Массив в Solidity — это, по сути, структура с такой структурой.

struct Array{
  mapping(uint => someType) items;
  uint length;
}

И если вы хотите использовать сопоставление, вам нужно сохранить длину сопоставления.

Таким образом, в основном реализация сопоставлений лучше с точки зрения стоимости?
Я бы использовал массив, потому что у вас есть ключ uint, и я думаю, что это будет проще, чем сопоставление. productsOnSale.length; - вы берете длину своего массива. productsOnSale.push(value);- вы добавляете новый элемент в конец массива. При сопоставлении, если вы будете использовать существующий ключ, вы перезапишете его.

Есть ли недостатки использования сопоставлений вместо массива?

Да, вот аспект, который вы не учли в своем вопросе:

У вас нет возможности отслеживать все ключи, которые вы установили в сопоставлении (кроме, конечно, сканирования всей цепочки блоков).

Вы можете генерировать событие для каждой вставки, что упростит отслеживание, но это, очевидно, увеличит стоимость.

Вы можете хранить все вне сети (например, на своем сервере), но это сделает вашу систему уязвимой для уязвимостей вне сети (например, кто-то взломает ваш сервер).

Самый простой способ отслеживать все ключи, установленные в сопоставлении, — это поместить эти ключи во вспомогательный массив.

Или в вашем случае, как вы упомянули, просто используйте массив вместо сопоставления для начала.

Я могу отслеживать все ключи сопоставления, используя сопоставление indexToProduct. Где каждый ключ хранится относительно значения индекса. Что-то вроде элемента в индексе. Так что я могу повторять totalProductsOnSaleи indexToProduct(i)получать список всех ключей.