Constants are similar to variables; however, there are a few differences:
impl
scope. mut
keyword cannot be used with constants. const ID: u32 = 0;
Constant initializer expressions can be quite complex, but they cannot use, for
instance, assembly instructions, storage access, mutable variables, loops and
return
statements. Although, function calls, primitive types and compound data
structures are perfectly fine to use:
fn bool_to_num(b: bool) -> u64 {
if b {
1
} else {
0
}
}
fn arr_wrapper(a: u64, b: u64, c: u64) -> [u64; 3] {
[a, b, c]
}
const ARR2 = arr_wrapper(bool_to_num(1) + 42, 2, 3);
Associated constants are constants associated with a type and can be declared in an impl
block or in a trait
definition.
Associated constants declared inside a trait
definition may omit their initializers to indicate that each implementation of the trait must specify those initializers.
The identifier is the name of the constant used in the path. The type is the type that the definition has to implement.
You can define an associated const directly in the interface surface of a trait:
script;
trait ConstantId {
const ID: u32 = 0;
}
Alternatively, you can also declare it in the trait, and implement it in the interface of the types implementing the trait.
script;
trait ConstantId {
const ID: u32;
}
struct Struct {}
impl ConstantId for Struct {
const ID: u32 = 1;
}
fn main() -> u32 {
Struct::ID
}
impl self
Constants Constants can also be declared inside non-trait impl
blocks.
script;
struct Point {
x: u64,
y: u64,
}
impl Point {
const ZERO: Point = Point { x: 0, y: 0 };
}
fn main() -> u64 {
Point::ZERO.x
}
Configurable constants are special constants that behave like regular constants in the sense that they cannot change during program execution, but they can be configured after the Sway program has been built. The Rust and TS SDKs allow updating the values of these constants by injecting new values for them directly in the bytecode without having to build the program again. These are useful for contract factories and behave somewhat similarly to immutable
variables from languages like Solidity.
Configurable constants are declared inside a configurable
block and require a type ascription and an initializer as follows:
configurable {
U8: u8 = 8u8,
BOOL: bool = true,
ARRAY: [u32; 3] = [253u32, 254u32, 255u32],
STR_4: str[4] = __to_str_array("fuel"),
STRUCT: StructWithGeneric<u8> = StructWithGeneric {
field_1: 8u8,
field_2: 16,
},
ENUM: EnumWithGeneric<bool> = EnumWithGeneric::VariantOne(true),
}
At most one configurable
block is allowed in a Sway project. Moreover, configurable
blocks are not allowed in libraries.
Configurable constants can be read directly just like regular constants:
fn return_configurables() -> (u8, bool, [u32; 3], str[4], StructWithGeneric<u8>) {
(U8, BOOL, ARRAY, STR_4, STRUCT)
}