Skip to content

Commit d39c92d

Browse files
authored
Update CH-14, Memory Management to add LazyCell and LazyLock (#745)
* feat: Added examples for `LazyCell` and `LazyLock` * fix: updated `mem.md` to list all examples * fix: make `LazyLock` and `LazyCell` examples demonstrate realistic applications
1 parent df006ba commit d39c92d

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

src/mem.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@
33
| Recipe | Crates | Categories |
44
|--------|--------|------------|
55
| [Declare lazily evaluated constant][ex-lazy-constant] | [![lazy_static-badge]][lazy_static] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
6+
| [Std::cell][ex-std-oncecell] | [![std-badge]][std] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
7+
| [`std::cell:LazyCell`][ex-std-lazycell] | [![std-badge]][std] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
8+
| [`std::sync::LazyLock`][ex-std-lazylock] | [![std-badge]][std] | [![cat-caching-badge]][cat-caching] [![cat-rust-patterns-badge]][cat-rust-patterns] |
69

710
[ex-lazy-constant]: mem/global_static.html#declare-lazily-evaluated-constant
11+
[ex-std-oncecell]: mem/global_static.html#stdcell
12+
[ex-std-lazycell]: mem/global_static.html#stdcelllazycell
13+
[ex-std-lazylock]: mem/global_static.html#stdsynclazylock
14+
815

916
{{#include links.md}}

src/mem/global_static/lazy-constant.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,76 @@ fn main() {
5353
```
5454

5555
[`OnceCell`]: https://doc.rust-lang.org/beta/std/cell/struct.OnceCell.html
56+
57+
## `std::cell::LazyCell`
58+
[`LazyCell`] and its thread-safe counterpart [`LazyLock`] can be used to create a value which is initialized on the first access.
59+
```rust,edition2021
60+
use std::cell::LazyCell;
61+
62+
struct User {
63+
id: u32,
64+
username: String,
65+
// We defer the expensive permission calculation
66+
permissions: LazyCell<Vec<String>>,
67+
}
68+
69+
impl User {
70+
fn new(id: u32, username: String) -> Self {
71+
Self {
72+
id,
73+
username,
74+
permissions: LazyCell::new(|| {
75+
println!("--- Fetching permissions from database for ID {} ---", id);
76+
// Simulate a heavy operation
77+
vec!["read".to_string(), "write".to_string()]
78+
}),
79+
}
80+
}
81+
}
82+
83+
fn main() {
84+
let user = User::new(1, "ferris_rustacean".into());
85+
86+
println!("User {} loaded.", user.username);
87+
88+
// If we never access user.permissions, the closure is never run.
89+
90+
if true { // Imagine a conditional check here
91+
println!("Permissions: {:?}", *user.permissions);
92+
}
93+
```
94+
95+
[`LazyCell`]: https://doc.rust-lang.org/std/cell/struct.LazyCell.html
96+
97+
## `std::sync::LazyLock`
98+
99+
The [`LazyLock`] type is a thread-safe alternative to [`LazyCell`].
100+
```rust,edition2024
101+
use std::sync::LazyLock;
102+
use std::collections::HashMap;
103+
104+
struct Config {
105+
api_key: String,
106+
timeout: u64,
107+
}
108+
109+
// Imagine loading this from a .env file or a vault
110+
static APP_CONFIG: LazyLock<Config> = LazyLock::new(|| {
111+
println!("Loading configuration...");
112+
Config {
113+
api_key: std::env::var("API_KEY").unwrap_or_else(|_| "default_key".to_string()),
114+
timeout: 30,
115+
}
116+
});
117+
118+
fn main() {
119+
println!("App started.");
120+
121+
// The closure above isn't run until we access APP_CONFIG here.
122+
let timeout = APP_CONFIG.timeout;
123+
124+
println!("Timeout is: {}s", timeout);
125+
println!("API Key is hidden: {}", APP_CONFIG.api_key.len() > 0);
126+
}
127+
```
128+
[`LazyLock`]: https://doc.rust-lang.org/std/sync/struct.LazyLock.html

0 commit comments

Comments
 (0)