Член сопоставления не инициализируется при создании структуры

 pragma solidity ^ 0.4 . 0 ; contract TestcaseResetObject   { 

     MyObject  ob ; 

     struct   MyObject   { mapping ( uint8 =>   uint )  map ; 
     } 

     event   Output ( uint  number ); 

     function  makeNew ()   { ob =   MyObject (); ob . map [ 0 ]   +=   1 ; 
         Output ( ob . map [ 0 ]); 
     } 
 } 

Когда я многократно запускаю makeNew в браузерной makeNew , я ожидаю, что получу каждый раз событие Output(1) . Вместо этого я получаю Output(1) , Output(2) , Output(3) и т. Д.

Кажется, когда я создаю новый MyObject , карта фактически не создается снова.

Другой вопрос касается того, что вновь инициализированная структура должна иметь нулевое значение во всех ее членах. Это кажется верным для uint и т. Д., Но поскольку отображение, похоже, «запоминает» свои старые значения, это, похоже, не так.

Есть идеи?

Ответы (2)

Согласитесь с Гизеппе. Код не «инициализирует» новый объект ob, а просто ссылается на существующий.

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

 pragma solidity ^ 0.4 . 0 ; contract TestcaseResetObject   { 

     uint   public  objectCount ; 

     struct   MyObjectStruct   { mapping ( uint   =>   uint )  map ; 
     } 

     MyObjectStruct []  myObjects ; 

     event   LogOutput ( uint  number ); 

     function  makeNewObject ()   public  returns ( uint  count )   { 

         MyObjectStruct  memory mo ; objectCount =  myObjects . push ( mo ); 
         return  objectCount ; 
     } 

     // object numbers start at 0 when objectCount is 1 
     function  incCounter ( uint  objectNumber ,   uint  index )   public  returns ( uint  newValue )   { myObjects [ objectNumber ]. map [ index ]   +=   1 ; 
         LogOutput ( myObjects [ objectNumber ]. map [ index ]); 
         return  myObjects [ objectNumber ]. map [ index ]; 
     } 
 } 

Давайте вам « makeNewObject » создайте новые сопоставления и « incCounter » incCounter конкретное сопоставление из массива и определенное место внутри сопоставления для увеличения.

Надеюсь, это поможет.

Немного изменил код (форматирование), вручную протестировал ремикс, чтобы он работал.

Отображение - это действительно определенный тип, и он отличается от простого массива. Из официальной документации :

Сопоставления можно рассматривать как хеш-таблицы, которые практически инициализируются так, что каждый возможный ключ существует и сопоставляется со значением, байтовое представление которого - все нули: значением по умолчанию для типа. Однако на этом сходство заканчивается: данные ключа на самом деле не хранятся в отображении, только их хеш keccak256 используется для поиска значения.

Из-за этого сопоставления не имеют длины или понятия «установленного» ключа или значения.

По сути это означает, что вы на самом деле никогда не инициализируете полную переменную отображения (в вашем случае, используя MyObject() вы инициализируете структуру ob , а не переменную map ).

Во второй раз, когда вы обращаетесь к map[0] она правильно указывает на ту же позицию, что и раньше, и поэтому вы находите старое значение.