Constants in Haxe
For non-static variables and objects, you can give them shallow constness as shown below:
public var MAX_COUNT(default, never):Int = 100;
This means you can read the value in the 'default' way but can 'never' write to it.
More info can be found http://adireddy.github.io/haxe/keywords/never-inline-keywords.
The usual way to declare a constant in Haxe is using the static
and inline
modifiers.
class Main {
public static inline var Constant = 1;
static function main() {
trace(Constant);
trace(Test.Constant);
}
}
If you have a group of related constants, it can often make sense to use an enum abstract
. Values of enum abstracts are static
and inline
implicitly.
Note that only the basic types (Int
, Float
, Bool
) as well as String
are allowed to be inline
, for others it will fail with this error:
Inline variable initialization must be a constant value
Luckily, Haxe 4 has introduced a final
keyword which can be useful for such cases:
public static final Regex = ~/regex/;
However, final
only prevents reassignment, it doesn't make the type immutable. So it would still be possible to add or remove values from something like static final Values = [1, 2, 3];
.
For the specific case of arrays, Haxe 4 introduces haxe.ds.ReadOnlyArray
which allows for "constant" lists (assuming you don't work around it using casts or reflection):
public static final Values:haxe.ds.ReadOnlyArray<Int> = [1, 2, 3];
Values = []; // Cannot access field or identifier Values for writing
Values.push(0); // haxe.ds.ReadOnlyArray<Int> has no field push
Even though this is an array-specific solution, the same approach can be applied to other types as well. ReadOnlyArray<T>
is simply an abstract type that creates a read-only "view" by doing the following:
- it wraps
Array<T>
- it uses
@:forward
to only expose fields that don't mutate the array, such aslength
andmap()
- it allows implicit casts
from Array<T>
You can see how it's implemented here.