As a developer, you can consider the mapping as all possible key/value pairs, with the values initialized to 0, false, empty array, etc. according to type. No need to initialize explicitly. They just are.
This includes mappings inside structs. Values will stay zeroish until explicitly set.
Mappings inside structs can be useful, as well as mappings of structs, or both as below.
Keys are not stored in mappings.
Consider mapping(uint => address) numberedAddresses;
The key (uint
) is hashed to find a "slot" and an address
is stored in that slot. The key itself is not stored. The only way to retrieve a mapped value is to call it back using knowledge of the key:
numberedAddress[key];
There are some implications to get acquainted with. It's not possible to enumerate the keys in a mapping. Similarly, it's not possible to count them. We could say "all possible keys exist" in all cases.
If one wants to list the keys we actually set (common) then one needs to store the keys themselves elsewhere. There are some example patterns here, e.g. Mapped Structs with Index, to help prevent re-inventing things. Are there well-solved and simple storage patterns for Solidity?.
The example below is meant for playing around in Remix. You'll get all 0 results for any key from the getters until you explicitly set something. The last two functions show how to work with a mapping that's stored inside a struct.
Hope it helps.
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;
}
}