The assignment process assigns a value to a variable. It is more complex for Solidity structs and arrays. In this tutorial, we will explain the default values of variables, how to assign to state and local variables, and how to destructure assignments.
This tutorial pays special attention to assignment for non-value types (such as an array in Solidity). It also discusses scoping, which indicates the variable availability within a function and a contract.
Contents
Solidity Struct: Main Tips
- Assignment sets values to variables.
- Tuple types allow returning several values at once.
- Assignment is complex for Solidity structs and arrays.
- Since 0.5.0 version, Solidity follows different scoping rules than before.
Destructuring Assignments and Returning Multiple Values
Internally, Solidity permits tuple types. They are applied to retrieve several values simultaneously. After that, these values can be set to new variables or already existing ones.
Note: tuple types are lists of objects that might be of different types. Their numbers are constant during the compiling.
pragma solidity >0.4.23 <0.7.0;
contract C {
uint[] data;
function f() public pure returns (uint, bool, uint) {
return (7, true, 2);
}
function g() public {
// Variables declared with type and assigned from the returned tuple,
// not all elements have to be specified (but the number must match).
(uint x, , uint y) = f();
// Common trick to swap values -- does not work for non-value storage types.
(x, y) = (y, x);
// Components can be left out (also for variable declarations).
(data.length, , ) = f(); // Sets the length to 7
}
}
Remember: Solidity uses tuple types only for forming syntactic groupings and expressions.
- Easy to use with a learn-by-doing approach
- Offers quality content
- Gamified in-browser coding experience
- The price matches the quality
- Suitable for learners ranging from beginner to advanced
- Free certificates of completion
- Focused on data science skills
- Flexible learning timetable
- Simplistic design (no unnecessary information)
- High-quality courses (even the free ones)
- Variety of features
- Nanodegree programs
- Suitable for enterprises
- Paid Certificates of completion
- A wide range of learning programs
- University-level courses
- Easy to navigate
- Verified certificates
- Free learning track available
- University-level courses
- Suitable for enterprises
- Verified certificates of completion
Struct and Array Assignment
The assignment is complicated for Solidity arrays and structs. The process of assigning to a state variable generates an independent copy. When assigning to a local variable, it creates independent copies only for elementary types.
Note: elementary types are static ones, fitting into 32 bytes.
Assigning non-value types from a state variable to a local variable makes the local variable have a reference to the initial state variable. Another assignment to the local variable does not change the state (only the reference).
Remember: the state changes during assignment to members of the local variable.
The following example shows that the call to g(x)
does not change x
since it generates an independent copy of the storage value in memory. On the other hand, h(x)
changes x
since it creates only the reference, not the copy.
pragma solidity >=0.4.16 <0.7.0;
contract C {
uint[20] x;
function f() public {
g(x);
h(x);
}
function g(uint[20] memory y) internal pure {
y[2] = 3;
}
function h(uint[20] storage y) internal {
y[3] = 4;
}
}
Scoping and Declaration
The default value of variables is set for all types. Here is a short list:
bool
has false.uint
andint
0.- Every separate element will be set to the default type value for the statically-typed array in Solidity and
bytes1
tobytes32
. - Dynamically-sized arrays, bytes, and strings have an empty array or string.
- The default value for the
enum
is its first member.
After declaration, variables become visible until the end of the smallest { }-block
, containing the declaration. However, variables defined as a part of a for-loop are visible until the end of the for-loop.
Note: when variables and other items are declared not in the code block, they become visible before the declaration. Such declaration can occur in functions, user-defined types and contracts.
The code below compiles without any issues because the two variables share the name, but do not have connected scopes:
pragma solidity >=0.5.0 <0.7.0;
contract C {
function minimalScoping() pure public {
{
uint same;
same = 1;
}
{
uint same;
same = 3;
}
}
}
This example illustrates that the first assignment to x
sets the outer and not the inner variable. As a result, a warning appears, stating that the outer variable is shadowed:
pragma solidity >=0.5.0 <0.7.0;
contract C {
function f() pure public returns (uint) {
uint x = 1;
{
x = 2; // this will assign to the outer variable
uint x;
}
return x; // x has value 2
}
}
Note: as of Solidity 0.5.0 version, the conventions for scoping have changed and no longer resemble JavaScript. Now, variables declared in any place within a function won’t be in the scope for the whole function.
In the following example, we show that following the old rules generates an error in later versions of Solidity:
pragma solidity >=0.5.0 <0.7.0;
// This will not compile
contract C {
function f() pure public returns (uint) {
x = 2;
uint x;
return x;
}
}
Solidity Struct: Summary
- During assignment, variables receive values.
- Tuple types can deliver multiple values at once.
- Array and struct Solidity types are more difficult than assigning values to elementary ones.
- 0.5.0 version changed the rules of scoping, and they no longer resemble JavaScript scoping.