Pointers carry many distinct characteristics. One important characteristic is the mutability via the const
keyword which controls how addresses and data can be mutated.
There are 4 basic const
combinations as it relates to pointers.
var x: *T // x is a mutable address to mutable data.
const x: *T // x is a constant address to mutable data.
var x: *const T // x is a mutable address to constant data.
const x: *const T // x is a constant address to constant data.
Much like a physical location, a valid pointer refers to a region that has been denoted with an address. In other words, we can find that region by following its address (much like locating a monument using coordinates).
The dual const
qualification means we can either change the address, or change the thing at the address, or some combination of the two.
Example 1: Constant address to mutable data
var x: usize = 42;
var y: usize = 43;
const ptr = &x; // the address is const, but the data is not.
ptr = &y; // this fails because we cannot change the address.
ptr.* += 1; // this succeeds because we can change the data.
Example 2: Mutable address to constant data
const x: usize = 42;
const y: usize = 43;
var ptr = &x; // the data is const, but the address is not.
ptr = &y; // this succeeds because we can change the address.
ptr.* += 1; // this fails because we cannot change the data.
Example 3: Mutable address to mutable data
var x: usize = 42;
var y: usize = 43;
var ptr = &x; // both the data and the address are mutable.
ptr = &y; // this succeeds because we can change the address.
ptr.* += 1; // this succeeds because we can change the data.
Example 4: Constant address to constant data
const x: usize = 42;
const y: usize = 43;
const ptr = &x; // both the data and the address are constant.
ptr = &y; // this fails because we cannot change the address.
ptr.* += 1; // this fails because we cannot change the data.
Explicitly declaring mutability
Mutable data can be viewed as constant by using the const
keyword on the pointer explicitly.
// the data itself is mutable
var x: usize = 42;
// the pointer sees the data as const
const ptr: *const usize = &x;
Note that this follows typical rules surrounding const
- const
qualification cannot be dropped without using @constCast
.
// the data itself is const
const x: usize = 42;
// this fails because the data is const
const ptr: *usize = &x;