Я обнаружил, что при инициализации структуры мы можем просто игнорировать тип сопоставления, например:
pragma solidity ^0.4.0;
contract C{
struct Person{
string name;
mapping(address=>int) map;
string[] nickNames;
int age;
}
function init() constant returns (string, int){
string[] memory nickNames = new string[](1);
nickNames[0] = "cat1099";
Person memory p = Person("Jack", nickNames, 23);
return (p.name, p.age);
}
}
В служебном документе я нашел только примечание к коду, в котором говорится: «Мы опускаем тип сопоставления». После поиска на этом сайте здесь кто-то сказал, что:
Сопоставления можно рассматривать как хеш-таблицы, которые виртуально инициализируются таким образом, что каждый возможный ключ существует и отображается на значение, байтовое представление которого состоит из нулей: значение типа по умолчанию. Однако на этом сходство заканчивается: данные ключа на самом деле не хранятся в отображении, только его хэш keccak256 используется для поиска значения.
Означает ли это, что solidty не может инициализировать сопоставление в структуре, поэтому просто игнорируйте его. Может ли кто-нибудь прояснить это, поскольку официального объяснения этому нет?
Как разработчик, вы можете рассматривать сопоставление как все возможные пары ключ/значение со значениями, инициализированными 0, false, пустым массивом и т. д. в зависимости от типа. Нет необходимости инициализировать явно. Они просто есть.
Сюда входят сопоставления внутри структур. Значения останутся нулевыми, пока не будут явно установлены.
Могут быть полезны сопоставления внутри структур, а также сопоставления структур или и то, и другое, как показано ниже.
Ключи не хранятся в сопоставлениях.
Учитыватьmapping(uint => address) numberedAddresses;
Ключ ( uint
) хешируется, чтобы найти «слот», и address
сохраняется в этом слоте. Сам ключ не сохраняется. Единственный способ получить сопоставленное значение — это вызвать его обратно, используя знание ключа:
numberedAddress[key];
Есть некоторые последствия для ознакомления. Невозможно перечислить ключи в отображении. Точно так же невозможно их сосчитать. Мы могли бы сказать, что «существуют все возможные ключи» во всех случаях.
Если кто-то хочет перечислить ключи, которые мы фактически установили (общие), тогда нужно хранить сами ключи в другом месте. Здесь есть несколько примеров шаблонов, например Mapped Structs with Index, которые помогают предотвратить повторное изобретение вещей. Существуют ли хорошо решенные и простые шаблоны хранения для Solidity? .
Пример ниже предназначен для игры в Remix. Вы получите все 0 результатов для любого ключа от геттеров, пока не установите что-то явно. Последние две функции показывают, как работать с отображением, хранящимся внутри структуры.
Надеюсь, это поможет.
pragma solidity ^0.4.6;
contract Mappings {
// For all new structs, all answer flags at all key locations are false until set.
struct UserStruct {
uint balanceOf;
bool isActive;
mapping(uint => bool) answerFlags;
}
// Key => Struct. All keys initialize to 0.
// Query any unset Key and get balanceOf == 0 and isActive == false.
// (More common to use address => struct for "users")
mapping(uint => UserStruct) public userStructs;
// Key => Bool. All keys initialize to false
// Query any unset key and get false.
mapping(uint => bool) public addressFlags;
// Set values in storage
function setUserStruct(uint key, uint balanceOf, bool isActive) public returns(bool success) {
userStructs[key].balanceOf = balanceOf;
userStructs[key].isActive = isActive;
return true;
}
function setAddressFlag(uint key, bool flagAddress) public returns(bool success) {
addressFlags[key] = flagAddress;
return true;
}
// Mapping inside a struct
function getUserAnswerFlag(uint userStructKey, uint userAnswerKey) public constant returns(bool answerFlag) {
return userStructs[userStructKey].answerFlags[userAnswerKey];
}
function setUserAnswerFlag(uint userStructKey, uint userAnswerKey, bool setValue) public returns(bool success) {
userStructs[userStructKey].answerFlags[userAnswerKey] = setValue;
return true;
}
}