Unlike variables, constants cannot change. Their values are calculated in compile-time and cannot change during execution.
Constant initializations must be relatively simple and only rely on values known during compilation. If you add two numbers for example, the compiler will calculate the result during build and put the result in your compiled code.
You can read constants both in receivers and in getters.
Unlike contract variables, constants don't consume space in persistent state. Their values are stored directly in the code cell.
There isn't much difference between constants defined outside of a contract and inside the contract. Those defined outside can be used by other contracts in your project.
All Examplesimport "@stdlib/deploy"; contract Integers with Deployable { // contract persistent state variables i1: Int as uint128 = 3001; i2: Int as int32 = 57; init() {} receive("show ops") { let i: Int = -12; // temporary variable, runtime Int type is always int257 (range -2^256 to 2^256 - 1) dump(i); i = self.i1 * 3 + (self.i2 - i); // basic math expressions dump(i); i = self.i1 % 10; // modulo (remainder after division), 3001 % 10 = 1 dump(i); i = self.i1 / 1000; // integer division (truncation toward zero), 3001 / 1000 = 3 dump(i); i = self.i1 >> 3; // shift right (divide by 2^n) dump(i); i = self.i1 << 2; // shift left (multiply by 2^n) dump(i); i = min(self.i2, 11); // minimum between two numbers dump(i); i = max(self.i2, 66); // maximum between two numbers dump(i); i = abs(-1 * self.i2); // absolute value dump(i); dump(self.i1 == 3001); dump(self.i1 > 2000); dump(self.i1 >= 3002); dump(self.i1 != 70); } }