Search code examples
rustinitializationdelayborrow-checker

How to use delayed initialization in rust code and pass compiler "possibly-uninitialized variable" rule?


The following rust code is a simplified version, my code needs to use delayed initialization, I want to know how to eliminate the error.

fn main() {
    let header: Vec<char>;
    let index = 0;
    if index == 0 {
        header = "abc".chars().collect();
        println!("{:?}", header);
    }
    println!("{}", header.len());
}

quote error[E0381]: borrow of possibly-uninitialized variable: header

--> src/main.rs:8:22

  |
8 |     println!("{:?}", header.len());
  |                      ^^^^^^ use of possibly-uninitialized `header`

I know there are two solutions to get rid of the error, including:

  1. let header: Vec = vec![];
  2. add else block with header = ..;

But they are all not the desired way!


Solution

  • The more common pattern is to use Option and later call unwrap(), but if it really must be allocated then later written, this is what MaybeUninit is for. You create some uninitialized memory, then initialize it, then tell the compiler it has been initialized. The API is analogous to Option, except that you would fill with data rather than reassigning or replacing.

    let mut header = std::mem::MaybeUninit::<Vec<char>>::uninit();
    let index = 0;
    if index == 0 {
        unsafe {
            header.as_mut_ptr().write("abc".chars().collect());
        }
        println!("{:?}", header);
    }
    let header = unsafe { std::mem::MaybeUninit::assume_init(header) };
    println!("{}", header.len());