Consider the case where a function returns a Result
:
fn might_explode() -> Result<AllFine, Kaboom> {
// Awesome, potentially explosive things.
}
Let us assume that I have no control, and I cannot make assumptions, over AllFine
(e.g., it comes from another crate). What I would like to do is to fill, if possible, an array of AllFine
with values obtained by iteratively invoking might_explode()
. If any of the invocations to might_explode()
returns an Err
, I would like to return that Err
.
For example, if I wanted to build an array of four elements, I would do:
let my_array = [might_explode()?, might_explode()?, might_explode()?, might_explode()?]
The above indeed works nicely, but for large arrays (I will be working, e.g., with arrays as big as 256 elements) it becomes extremely cumbersome and (I guess?) it makes the resulting binary very bloated.
Looking around for possible solutions, I stumbled upon this beautiful post that seems to do exactly what I need. Using a bit of unsafe
, the post above presents this example:
let _: [Option<String>; 33] = unsafe {
let mut arr: [Option<String>; 33] = std::mem::uninitialized();
for item in &mut arr[..] {
std::ptr::write(item, None);
}
arr
};
Now, this would be just perfect for me if only might_explode()
always returned AllFine
. But sometimes it might return Kaboom
! As a result, I might be caught halfway through the initialization of the array, and in returning I'd call a potentially deadly drop
on every non-initialized element of the array.
So, is there a way to reasonably use unsafe
to achieve what I want to do?