Reference Types Explained: Arrays, Structs, Mappings, Strings
Learning Objectives
Master the definition and usage of the four reference types in Solidity: arrays, structs, mappings, and strings/variable-length byte arrays.
Prerequisites
Familiarity with value types (integers, booleans, addresses, fixed-length byte arrays, etc.) is assumed.
Arrays
Arrays in storage
Arrays in Solidity are divided into two types:
- Static arrays
T[K]: Fixed length, determined at compile time - Dynamic arrays
T[]: Variable length, dynamically increased or decreased at runtime
Key rules:
push()/pop()can only operate on dynamic arrays in storagepublicarrays automatically generate getter functions with the index as a parameter- Array elements can be of any type, including structs and mappings
Arrays in memory
- Must be initialized with the
newkeyword, and the length must be determined at creation - Length is fixed after creation, cannot use push / pop
- Suitable for temporary calculations within functions
Complete Example
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;
contract ArrayType {
uint8[3] data; // storage static array
uint8[] ddata; // storage dynamic array
// Returns a static array (copied to memory for return)
function testStaticArray() public view returns(uint8[3] memory) {
return data;
}
// Reads a dynamic array
function testReadDynamicArray() public view returns(uint8[] memory) {
return ddata;
}
// Dynamic array write operations
function testWriteDynamicArray() public {
ddata.push(12);
ddata.pop();
ddata.push(90);
}
// Dynamic array in memory
function testMemoryDynamicArray(uint8 size) public pure returns(uint8[] memory) {
uint8[] memory mdata = new uint8[](size); // Must be initialized, cannot push/pop
return mdata;
}
}
Structs
Basic Concepts
Structs are used to define custom data types, similar to contract and enum, they are user-defined types.
Features:
- Can be used as state variables, local variables, function parameters, and return values
- Can be placed within mappings and arrays
- Members can be mappings or arrays
Basic Example
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;
contract StructType {
struct Person {
string name;
uint8 age;
}
Person master;
function readPerson() public view returns(Person memory) {
return master;
}
function writePerson(Person memory p) public {
master = p;
}
function writePersonName(string memory name) public {
master.name = name;
}
// Structs in memory do not require 'new'
function testMemoryStruct() public pure returns(Person memory) {
Person memory p;
p.name = "zhangsan";
p.age = 25;
return p;
}
// storage local variable points to the data block of the member variable
function testStorageLocalStruct() public view returns(Person memory) {
Person storage p = master;
// Modifying p will directly modify master!
return p;
}
}
Advanced Example: Combination of Structs with Arrays and Mappings
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.23;
contract Structs {
struct Car {
string model;
uint year;
address owner;
}
Car public car;
Car[] public cars;
mapping(address => Car[]) public carsByOwner;
function examples() external {
// Three initialization methods
Car memory toyota = Car("Toyota", 1990, msg.sender);
Car memory lambo = Car({year: 1980, model: "Lamborghini", owner: msg.sender});
Car memory tesla;
tesla.model = "Tesla";
tesla.year = 2010;
tesla.owner = msg.sender;
cars.push(toyota);
cars.push(lambo);
cars.push(tesla);
carsByOwner[msg.sender].push(toyota);
cars.push(Car("Ferrari", 2020, msg.sender));
// storage reference can modify original data
Car storage _car = cars[0];
_car.year = 1999;
// Delete field (reset to default value)
delete _car.owner;
delete cars[1];
}
}
Note:
deletedoes not remove an element from an array, but rather resets the corresponding position to its default value (zero value). The array length remains unchanged.
Mappings
Declaration Syntax
mapping(keyType => valueType) visibility variableName;
Type Constraints
- keyType: Any elementary type (
uint,address,bool,bytes,string, etc.), cannot be user-defined complex types (structs, mappings, arrays) - valueType: Any type, including mappings (nested mappings)
Usage Restrictions
- Can only be used as state variables, storage local variables, library function parameters
- Cannot be used as parameters or return values for public functions
publicmappings automatically generate getter functions (with the key as a parameter)- Cannot be iterated (due to the storage layout design, keys are scattered after hashing)
Example
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;
contract MappingType {
mapping(string => uint8) public ages;
function getAge(string memory name) public view returns(uint8) {
return ages[name];
}
function setAge(string memory name, uint8 age) public {
ages[name] = age;
}
}
Tip: Accessing a non-existent key in a mapping will not throw an error; instead, it returns the default value of the valueType (e.g.,
uintreturns 0,addressreturns0x0).
Variable-length Byte Arrays and Strings
bytes vs. string
bytes and string are both reference types (not value types), and their underlying storage structure is similar to dynamic arrays.
Key differences:
stringis a UTF-8 encoded byte array, individual characters cannot be accessed by indexbytesis a raw byte array, and can be accessed by index- Solidity does not have built-in string manipulation functions (concatenation, substring, etc., require a library or conversion to
bytesfor operations) stringandbytescan be converted to each other (without copying data)
Usage Rules
| Scenario | Recommended Type |
|---|---|
| Raw data of arbitrary length | bytes |
| Strings (text) of arbitrary length | string |
| Fixed-length data (1~32 bytes) | bytes1 ~ bytes32 (value type, saves more gas) |
Example
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;
contract BytesAndString {
string name = "BytesAndString";
bytes name1 = "BytesAndString1";
function testStringAndBytes() public view returns(string memory) {
string memory data = "xyz";
bytes memory data1 = "abc";
// Copy from storage to memory
data = name;
data1 = name1;
// Type conversion
data1 = bytes(data);
data = string(data1);
return data;
}
}
Summary
| Type | Key Features |
|---|---|
| Array | storage can be dynamically increased/decreased, memory is fixed-length; push/pop only for storage dynamic arrays |
| Struct | Custom composite type; no new needed in memory; storage local variables are references |
| Mapping | Key-value storage; not iterable; cannot be function parameters/return values |
| string/bytes | Reference type; string not indexable; fixed length prefers bytesN to save gas |
Next Article: Storage Locations and Copying Mechanism — Understand the differences between storage, memory, calldata, and the copying rules for reference types.
主题测试文章,只做测试使用。发布者:Walker,转转请注明出处:https://walker-learn.xyz/archives/7489