In Solidity's documentation, the term "value types" is sometimes used in a broad sense to include any type that can be assigned a value directly. This can be a bit confusing because "value type" in many programming language contexts refers to types that are passed by value (i.e., a copy is made on assignment or when passed to functions).
In the case of Solidity:
Value types are types that have their data directly stored in the location you assign it to. This is opposed to reference types, where the location contains a pointer to the actual data. The basic data types like bool
, int
, uint
, and fixed-size byte arrays like bytes1
, bytes2
, ..., bytes32
are typical value types because they are passed by value — a copy is made when they are passed to functions or used in assignments.
Dynamic types like bytes
and string
are a bit different. They behave like value types in the sense that you can assign values to them directly, but they're stored in a way that's more akin to reference types. For these types, the variable that you interact with actually holds a reference to the location of the data, not the data itself, because the size of the data can change.
The Solidity documentation places bytes
and string
under the "Value Types" section likely because they are not objects or structs, which are traditional reference types in many languages. However, the term "Not a value-type!" is there to clarify that they are not value types in the strictest sense — they are special cases.
Here's why bytes
and string
are special:
- They are dynamically-sized, meaning they can grow in length, which is not something value types can typically do.
- They are passed by reference in function calls internally to save on gas costs, even though syntactically they are treated as value types.
- They do not have a fixed size at compile time; their size is determined at runtime.
This distinction is important for understanding how data is stored and how it is passed around in your smart contracts. It affects how you interact with the data, how you optimize for gas costs, and how you manage memory and storage.