Expand description
Scoped thread-local storage
This module provides the ability to generate scoped thread-local variables. In this sense, scoped indicates that thread local storage actually stores a reference to a value, and this reference is only placed in storage for a scoped amount of time.
There are no restrictions on what types can be placed into a scoped variable, but all scoped variables are initialized to the equivalent of null. Scoped thread local storage is useful when a value is present for a known period of time and it is not required to relinquish ownership of the contents.
§Examples
§Basic usage
use scoped_tls_hkt::scoped_thread_local;
scoped_thread_local!(static FOO: u32);
// Initially each scoped slot is empty.
assert!(!FOO.is_set());
// When inserting a value, the value is only in place for the duration
// of the closure specified.
FOO.set(&1, || {
FOO.with(|slot| {
assert_eq!(*slot, 1);
});
});
§Mutable value
use scoped_tls_hkt::scoped_thread_local;
scoped_thread_local!(static mut FOO: u32);
// Initially each scoped slot is empty.
assert!(!FOO.is_set());
// When inserting a value, the value is only in place for the duration
// of the closure specified.
let mut x = 1;
FOO.set(&mut x, || {
FOO.with(|slot| {
assert_eq!(*slot, 1);
// We can mutate the value
*slot = 42;
});
});
// Changes will be visible externally
assert_eq!(x, 42);
§Higher-kinded types
use scoped_tls_hkt::scoped_thread_local;
// Must implement Copy
#[derive(Copy, Clone)]
struct Foo<'a> {
x: &'a str, // Lifetime is covariant
y: i32,
}
scoped_thread_local!(static FOO: for<'a> Foo<'a>);
// Initially each scoped slot is empty.
assert!(!FOO.is_set());
// When inserting a value, the value is only in place for the duration
// of the closure specified.
FOO.set(Foo { x: "Hello", y: 42 }, || {
FOO.with(|slot| {
assert_eq!(slot.x, "Hello");
assert_eq!(slot.y, 42);
});
});
§Mutable higher-kinded types
For mutable HKTs, the types must implement the ReborrowMut
trait, and the Result
associated type should be the Self
type, but with
the lifetime substituted with the trait’s lifetime parameter.
The ReborrowMut
trait is implemented automatically for
many built-in types, including primitive types, references, mutable
references and tuples (up to length 10). Where this is insufficient, you
can implement the trait yourself: doing so should not require any unsafe
code.
use scoped_tls_hkt::scoped_thread_local;
scoped_thread_local!(static mut FOO: for<'a> (&'a mut i32, &'a mut f32));
// Initially each scoped slot is empty.
assert!(!FOO.is_set());
// References to local variables can be stored.
let mut x = 1;
let mut y = 2.0;
FOO.set((&mut x, &mut y), || {
FOO.with(|(u, v)| {
assert_eq!(*u, 1);
assert_eq!(*v, 2.0);
*u = 42;
});
});
assert_eq!(x, 42);
Macros§
- The macro. See the module level documentation for the description and examples.
Structs§
- Type representing a thread local storage key corresponding to a reference to the type parameter
T
. - Type representing a thread local storage key corresponding to a mutable reference to the type parameter
T
.
Traits§
- Trait representing the act of “reborrowing” a mutable reference to produce a new one with a shorter lifetime.