Best practices when using Structs

Like in object oriented programming, you can create composite datatypes via structs .

Structs can contain functions and other complex datatypes like mappings and arrays. These arrays and mappings can even contain more structs. However, structs cannot directly contain other structs (unless they are values in mappings or arrays).

Let’s step through what to do and what not to do when working with structs:

How to initialize a struct

Here’s an example from Solidity docs on how to declare structs:

struct Funder {

address addr;

uint amount;

}



struct StructOfStructs {

...

mapping (uint => Funder) funders;

}

There are various syntaxes for initializing a struct.

You can directly pass values into the struct object:

... = Funder(msg.sender, msg.value);

2. Or, you can use object notation to pass values into the struct object, for better readability:

... = Funder({addr: msg.sender, amount: msg.value})

Common usage patterns (memory vs storage)

You can have single, globally declared struct objects in your contract, but that defeats the purpose for creating a new datatype.

More commonly, you’ll use an array or a mapping to save a collection of structs. For example, let’s create an array of Funders and a mapping of Funders .

An array of Funders:

Funders[] public funders; function ... {

Funder memory f;

f.address = ...;

f.amount = ...;

funders.push(f);

}

Important to know: Struct declarations default to storage. You should always use a memory modifier when creating or copying structs. It is not recommended to use structs for any temporary computations inside functions.

A mapping of Funders:

mapping (uint => Funder) funders; function ... {

funders[index] = Funder(...);

}