macro_rules! app_local { ($( $(#[$meta:meta])* $vis:vis static $IDENT:ident : $T:ty = $(const { $init_const:expr })? $($init:expr)?; )+) => { ... }; }
Expand description
Declares new app local variable.
An app local is a static variable that is declared using the same syntax as thread_local!
, but can be
accessed by any thread in the app. In apps that only run once per process it compiles down to the equivalent
of a static LOCAL: RwLock<T> = const;
or static LOCAL: RwLock<Option<T>>
that initializes on first usage. In test
builds with multiple parallel apps it compiles to a switching storage that provides a different value depending on
what app is running in the current thread.
See AppLocal<T>
for more details.
§Multi App
If the crate is compiled with the "multi_app"
feature a different internal implementation is used that supports multiple
apps, either running in parallel in different threads or one after the other. This backing implementation has some small overhead,
but usually you only want multiple app instances per-process when running tests.
The lifetime of "multi_app"
locals is also more limited, trying to use an app-local before starting to build an app will panic,
the app-local value will be dropped when the app is dropped. Without the "multi_app"
feature the app-locals can be used at
any point before or after the app lifetime, values are not explicitly dropped, just unloaded with the process.
§Const
The initialization expression can be wrapped in a const { .. }
block, if the "multi_app"
feature is not enabled
a faster implementation is used that is equivalent to a direct static LOCAL: RwLock<T>
in terms of performance.
Note that this syntax is available even if the "multi_app"
feature is enabled, the expression must be const either way,
but with the feature the same dynamic implementation is used.
Note that const
initialization does not automatically convert the value into the static type.
§Examples
The example below declares two app locals, note that BAR
init value automatically converts into the app local type.
app_local! {
/// A public documented value.
pub static FOO: u8 = const { 10u8 };
// A private value.
static BAR: String = "Into!";
}
let app = LocalContext::start_app(AppId::new_unique());
assert_eq!(10, FOO.get());
Also note that an app context is started before the first use, in multi_app
builds trying to use an app local in
a thread not owned by an app panics.