r[items.const]
r[items.const.syntax]
ConstantItem -> `const` ( IDENTIFIER | `_` ) `:` Type ( `=` Expression )? `;`
r[items.const.intro] A constant item is an optionally named constant value which is not associated with a specific memory location in the program.
r[items.const.behavior] Constants are essentially inlined wherever they are used, meaning that they are copied directly into the relevant context when used. This includes usage of constants from external crates, and non-Copy
types. References to the same constant are not necessarily guaranteed to refer to the same memory address.
r[items.const.namespace] The constant declaration defines the constant value in the value namespace of the module or block where it is located.
r[items.const.static] Constants must be explicitly typed. The type must have a 'static
lifetime: any references in the initializer must have 'static
lifetimes. References in the type of a constant default to 'static
lifetime; see static lifetime elision.
r[items.const.static-temporary] A reference to a constant will have 'static
lifetime if the constant value is eligible for promotion; otherwise, a temporary will be created.
const BIT1: u32 = 1 << 0; const BIT2: u32 = 1 << 1; const BITS: [u32; 2] = [BIT1, BIT2]; const STRING: &'static str = "bitstring"; struct BitsNStrings<'a> { mybits: [u32; 2], mystring: &'a str, } const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings { mybits: BITS, mystring: STRING, };
r[items.const.final-value-immutable] The final value of a const
item cannot contain references to anything mutable.
r[items.const.expr-omission] The constant expression may only be omitted in a trait definition.
r[items.const.destructor]
Constants can contain destructors. Destructors are run when the value goes out of scope.
struct TypeWithDestructor(i32); impl Drop for TypeWithDestructor { fn drop(&mut self) { println!("Dropped. Held {}.", self.0); } } const ZERO_WITH_DESTRUCTOR: TypeWithDestructor = TypeWithDestructor(0); fn create_and_drop_zero_with_destructor() { let x = ZERO_WITH_DESTRUCTOR; // x gets dropped at end of function, calling drop. // prints "Dropped. Held 0.". }
r[items.const.unnamed]
r[items.const.unnamed.intro] Unlike an associated constant, a free constant may be unnamed by using an underscore instead of the name. For example:
const _: () = { struct _SameNameTwice; }; // OK although it is the same name as above: const _: () = { struct _SameNameTwice; };
r[items.const.unnamed.repetition] As with underscore imports, macros may safely emit the same unnamed constant in the same scope more than once. For example, the following should not produce an error:
macro_rules! m { ($item: item) => { $item $item } } m!(const _: () = ();); // This expands to: // const _: () = (); // const _: () = ();
r[items.const.eval]
Free constants are always evaluated at compile-time to surface panics. This happens even within an unused function:
// Compile-time panic const PANIC: () = std::unimplemented!(); fn unused_generic_function<T>() { // A failing compile-time assertion const _: () = assert!(usize::BITS == 0); }