Primitive Types
For simple values, Move has a number of built-in primitive types. They're the foundation for all other types. The primitive types are:
- Booleans
- Unsigned Integers
- Addresses - covered in the next section
Before we get to the primitive types, let's first take a look at how to declare and assign variables in Move.
Variables and assignment
Variables are declared using the let
keyword. They are immutable by default, but can be made
mutable by adding the mut
keyword:
let <variable_name>[: <type>] = <expression>;
let mut <variable_name>[: <type>] = <expression>;
Where:
<variable_name>
- the name of the variable<type>
- the type of the variable, optional<expression>
- the value to be assigned to the variable
let x: bool = true;
let mut y: u8 = 42;
A mutable variable can be reassigned using the =
operator.
y = 43;
Variables can also be shadowed by re-declaring them.
let x: u8 = 42;
let x: u16 = 42;
Booleans
The bool
type represents a boolean value - yes or no, true or false. It has two possible values:
true
and false
, which are keywords in Move. For booleans, the compiler can always infer the type from the value, so there is no need to explicitly specify it.
let x = true;
let y = false;
Booleans are often used to store flags and to control the flow of the program. Please refer to the Control Flow section for more information.
Integer Types
Move supports unsigned integers of various sizes, from 8-bit to 256-bit. The integer types are:
u8
- 8-bitu16
- 16-bitu32
- 32-bitu64
- 64-bitu128
- 128-bitu256
- 256-bit
let x: u8 = 42;
let y: u16 = 42;
// ...
let z: u256 = 42;
Unlike booleans, integer types sometimes require explicit type annotations. The compiler usually infers the type from context, defaulting to u64
when unspecified. In ambiguous cases, a type annotation is needed, which can be added during assignment or with a type suffix.
// Both are equivalent
let x: u8 = 42;
let x = 42u8;
Operations
Move supports the standard arithmetic operations for integers: addition, subtraction, multiplication, division, and modulus (remainder). The syntax for these operations is:
Syntax | Operation | Aborts If |
---|---|---|
+ | addition | Result is too large for the integer type |
- | subtraction | Result is less than zero |
* | multiplication | Result is too large for the integer type |
% | modulus (remainder) | The divisor is 0 |
/ | truncating division | The divisor is 0 |
For more operations, including bitwise operations, please refer to the Move Reference.
The types of the operands must match, or the compiler will raise an error. The result of the operation will be of the same type as the operands. To perform operations on different types, the operands need to be cast to the same type.
Casting with as
Move supports explicit casting between integer types. The syntax is as follows:
<expression> as <type>
Note that parentheses around the expression may be required to prevent ambiguity:
let x: u8 = 42;
let y: u16 = x as u16;
let z = 2 * (x as u16); // ambiguous, requires parentheses
A more complex example, preventing overflow:
let x: u8 = 255;
let y: u8 = 255;
let z: u16 = (x as u16) + ((y as u16) * 2);
Overflow
Move does not support overflow / underflow; an operation that results in a value outside the range of the type will raise a runtime error. This is a safety feature to prevent unexpected behavior.
let x = 255u8;
let y = 1u8;
// This will raise an error
let z = x + y;