You get a function that takes an index argument. It returns the scalar values in the struct, so everything that isn't itself a mapping or an array.
For instance:
pragma solidity 0.5.1;
contract StuctsGetter {
struct MyStruct {
uint a;
bytes32 b;
mapping(address => bool) active;
bytes32[] keys;
}
mapping(uint => MyStruct) public myStructs;
function setMyStruct(uint index, uint a, bytes32 b) public {
MyStruct storage m = myStructs[index];
m.a = a;
m.b = b;
}
}
You can call instance.myStructs(uint) to fetch the mapped struct at a certain index. It will return a and b but not active or keys.
Avoid a head-scratcher: If there isn't at least one scalar value (i.e. the struct is made entirely of mappings and/or arrays) then the compiler won't know how to construct the "free" getter. It will fail in a confusing way.
To set/get the indexed values in a mapped struct, write your own functions.
function appendKeyToMyStruct(uint _myStruct, address key) public ... {
myStructs[_myStruct].keys.push(key);
}
function getMyStructKey(uint _myStruct, uint row) public ... {
return myStructs[_myStruct].keys[row];
}
These patterns may give you some ideas: Are there well-solved and simple storage patterns for Solidity?
A little info about the storage pointer used in the example: https://blog.b9lab.com/storage-pointers-in-solidity-7dcfaa536089
Hope it helps.
O(n)) which we do not want, and client software can a) listen to events and b) iterate, therefore c) "return all" would be repetitive and costly in most cases. – Rob Hitchens Mar 02 '19 at 18:40