Static storage (reference)¶
This page specifies module static declarations: their syntax, storage, initialization, the operations on a static, aliases of a static, imports of a pub static, and the refusals. Refusals are reported with INCAN-T0001, and syntax errors with INCAN-P0001, unless a rule below names another code.
Syntax¶
static name: Type = expr
pub static name: Type = expr
- A
staticis declared at module scope, with a type annotation and an initializer. pub staticexports the static from its module.
Storage¶
- Each
staticdeclaration is one storage cell of its module. - A read of the static observes the cell's current value.
- An assignment, a compound assignment, a mutating method call, and a field or index assignment through the static change the cell.
- Inside its module, a static is assigned and compound-assigned by its name, without
mut.mutis not written on astaticdeclaration. - An imported
pub staticnames the exporting module's cell.
Initialization¶
- The initializer's type is the declared type.
- A static is initialized once, in declaration order.
- An initializer may read a
const, an earlier static, and call functions. - An initializer may not read a later static, directly or through a function it calls, and may not assign to a static through a function it calls.
- Statics may not depend on each other in a cycle.
Operations¶
get(key)on a staticdict[K, V], or on adict[K, V]field of a static, returnsOption[V]:Someholding a copy of the stored value when the key is present,Noneotherwise.- An argument passed to a method on a static is readable after the call.
static counter: int = 0
static items: list[int] = []
static counts: dict[str, int] = {}
def current() -> int:
return counter # accepted
def reset() -> None:
counter = 0 # accepted
def bump() -> None:
counter += 1 # accepted
def record(name: str) -> None:
items.append(len(items)) # accepted
counts[name] = counts.get(name, 0) + 1 # accepted
def lookup(name: str) -> Option[int]:
return counts.get(name) # accepted
Aliases¶
A new local bound directly to a static, x = s, let x = s or mut x = s, is an alias of the static's cell. The same holds when the binding is annotated with the static's type, spelled directly or through a type alias.
- A mutating method call and a field or index assignment through the alias change the static.
- A
forloop, a comprehension or a pattern that changes the static's items through a name it binds, over the alias as over the static, is refused (INCAN-T0001; see Assignments). - An assignment to the alias rebinds the local; the static keeps its value.
- A binding annotated with another type that accepts the static's value, such as
Option[int]for anintstatic, holds a copy of the value.
static items: list[int] = []
def add_defaults() -> None:
let live_items = items
live_items.append(1) # accepted
annotated: list[int] = items
annotated.append(2) # accepted
Imports¶
from counters import hits
import counters::hits
- Both forms bind the exported static
hitsofcounters, and name its cell. - A static declared without
pubis not exported:from counters import hitsof it is refused (INCAN-I0001; see Exports). - An imported static's name is not reassigned: an assignment or compound assignment to it is refused (
INCAN-T0001). - A mutating method call and a field or index assignment through an imported static change the exporting module's cell.
Refusals¶
| Form | Code |
|---|---|
static counter = 0: no type annotation |
INCAN-P0001 |
static counter: int: no initializer |
INCAN-P0001 |
static inside a function or other block |
INCAN-P0001 |
static mut counter: int = 0: mut on a static |
INCAN-P0001 |
| An initializer that reads a later static | INCAN-T0001 |
| Statics that depend on each other in a cycle | INCAN-T0001 |
| An initializer that assigns to a static through a function it calls | INCAN-T0001 |
An assignment or compound assignment to an imported static's name, hits = 0 or hits += 1, including as a target of a tuple or chained assignment |
INCAN-T0001 |
A for loop, comprehension or pattern that changes the items of a static, or of a local bound to one, through a name it binds |
INCAN-T0001 |
from counters import hits of a static declared without pub |
INCAN-I0001 |
An assignment or compound assignment to a const |
INCAN-T0001 |
get on a static dict, or on a dict field of a static, whose value type cannot be copied, such as a Generator (see Kept and in-place dict lookups) |
INCAN-T0118 |
static counter = 0 # refused: a static needs a type annotation
def bad() -> None:
static local: int = 0 # refused: static is declared at module scope
from counters import hits
def bad() -> None:
hits = 0 # refused: an imported static cannot be reassigned
hits += 1 # refused: an imported static cannot be reassigned