We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Errors Are Values step 6 of 24
Mutating an Option in place
Implement a cache that stores one optional integer. Process each operation, report its result, and append the number of computations performed.
pub fn run(ops: Vec<String>) -> Vec<i32>
Start with cache = None and computations = 0. Each operation appends
one integer, followed by one final integer for the computation count.
Empty input therefore returns [0].
| Operation | Cache change | Reported value |
|---|---|---|
get |
Compute and store a value only when empty | The cached value |
clear |
Replace the cache with None |
The previous value, or -1 |
set:N |
Store Some(N) |
The previous value, or -1 |
| Anything else | None | -1 |
Each computation increments computations, then returns
computations * 10. A cache hit or set does not increment the counter.
Inputs used here keep the counter and computed values within i32.
Operations are case-sensitive. Keep the supplied parser: after set:,
parse an i32 without trimming whitespace. A missing, invalid, or
out-of-range number stores zero.
Zero and negative numbers, including -1, are valid cached values.
Consequently, a reported -1 is ambiguous: it may be a stored value,
an empty-cache result, or an unknown operation. Internally, Option
preserves the distinction.
Follow a cache through four operations
For ["get", "get", "clear", "get"]:
| Step | Result | Cache afterward | Computations |
|---|---|---|---|
First get |
10 |
Some(10) |
1 |
Second get |
10 |
Some(10) |
1 |
clear |
10 |
None |
1 |
Third get |
20 |
Some(20) |
2 |
Append the final count to get [10, 10, 10, 20, 2].
Choose the operation that preserves the right value
| Method | Effect | Return value |
|---|---|---|
take() |
Leaves None |
The previous Option<T> |
replace(value) |
Stores Some(value) |
The previous Option<T> |
insert(value) |
Always stores the new value | A mutable reference to the new value |
get_or_insert(value) |
Inserts only when empty | A mutable reference to the stored value |
get_or_insert_with(f) |
Calls f and inserts its result only when empty |
A mutable reference to the stored value |
The argument to get_or_insert is evaluated before the method runs,
even on a cache hit. Put the computation inside the closure passed to
get_or_insert_with so that it runs only when needed.
The starter recomputes and overwrites on every get. It also discards the
previous value on clear and set. Use take and replace to
return those old values while changing the cache.
Taking ownership without cloning
take also works when the contained value is not Copy. It moves the
value out while leaving a valid None behind:
struct Pending {
message: Option<String>,
}
impl Pending {
fn take_message(&mut self) -> Option<String> {
self.message.take()
}
}
fn main() {
let mut pending = Pending { message: Some(String::from("ready")) };
assert_eq!(pending.take_message().as_deref(), Some("ready"));
assert_eq!(pending.take_message(), None);
}
Returning self.message directly from that method would attempt to move
a non-Copy field out through a mutable reference and produce E0507.
take transfers ownership without cloning the string.
Using the returned mutable reference
get_or_insert_with returns &mut i32. Dereferencing it copies the
integer for the output. You can then use the cache again without retaining
that reference.
If you keep the reference and use it later, an intervening access to the
cache may conflict with its mutable borrow. End the reference's use first,
or restructure the accesses. A non-Copy value does not automatically
require cloning; the right approach depends on whether the caller needs
to borrow, move, or duplicate it.
A passing submission must compile, pass the tests, and pass
clippy -D warnings.
See the Option methods for these mutation operations.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Rust reference solution
Sign in to track your attempts toward unlocking the reference solution.