dragonhaze
dragonhaze

Reputation: 319

borrow of possibly uninitialized variable for match operator

I was designing a library that would transliterate given string into English from Ukrainian, so I decided to use 'match' operator for defining statement with check of multiple conditions. But I bumped into compiler error, which is typical to Rust, but fully impossible in my situation(at least I suppose so).


   --> src/lib.rs:188:21
    |
188 |  origin_mutated[i] = 'Y';
    |  ^^^^^^^^^^^^^^ use of possibly-uninitialized `origin_mutated`

error: aborting due to previous error

Here is full code of a library. Please bump my nose into a problem, if I'm not seeing something obvious(because I have suspicion that it may be a bug in compiler)

pub fn transliterate(mut origin: String) -> String {
    let counter: usize = origin.chars().count();
    let mut j: usize = 0;
    let mut i: usize = 0;
    let origin_vec: Vec<char> = origin.chars().collect();
    let mut origin_mutated: Vec<char>;
    if j <= counter{
        while j <= counter {
            match origin_vec[j] {
                'А' => {
                    origin_mutated[i] = 'A';
                    i+=1;
                    j+=1;
                    },
                'Б' => {
                    origin_mutated[i] = 'B';
                    j+=1;
                    i+=1;
                    },
                'В' => {
                    origin_mutated[i] = 'V';
                    i+=1;
                    j+=1;
                    },
                'Г' => {
                    origin_mutated[i] = 'H';
                    i+=1;
                    j+=1;
                    },
                'Ґ' => {
                    origin_mutated[i] = 'G';
                    i+=1;
                    j+=1;
                    },
                'Д' => {
                    origin_mutated[i] = 'D';
                    i+=1;
                    j+=1;
                    },
                'Е' => {
                    origin_mutated[i] = 'E';
                    i+=1;
                    j+=1;
                    },
                'Є' => {
                    origin_mutated[i] = 'Y';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 'e';
                    i+=1;
                    },
                'Ж' => {
                    origin_mutated[i] = 'Z';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 'h';
                    i+=1;
                    },
                'З' => {
                    origin_mutated[i] = 'Z';
                    i+=1;
                    j+=1;
                    },
                'И' => {
                    origin_mutated[i] = 'Y';
                    i+=1;
                    j+=1;
                    },
                'І' => {
                    origin_mutated[i] = 'I';
                    i+=1;
                    j+=1;
                    },
                'Ї' => {
                    origin_mutated[i] = 'Y';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 'i';
                    i+=1;
                    },
                'Й' => {
                    origin_mutated[i] = 'Y';
                    i+=1;
                    j+=1;
                    },
                'К' => {
                    origin_mutated[i] = 'K';
                    i+=1;
                    j+=1;
                    },
                'Л' => {
                    origin_mutated[i] = 'L';
                    i+=1;
                    j+=1;
                    },
                'М' => {
                    origin_mutated[i] = 'M';
                    i+=1;
                    j+=1;
                    },
                'Н' => {
                    origin_mutated[i] = 'N';
                    i+=1;
                    j+=1;
                    },
                'О' => {
                    origin_mutated[i] = 'O';
                    i==1;
                    j+=1;
                    },
                'П' => {
                    origin_mutated[i] = 'P';
                    i+=1;
                    j+=1;
                    },
                'Р' => {
                    origin_mutated[i] = 'R';
                    i==1;
                    j+=1;
                    },
                'С' => {
                    origin_mutated[i] = 'S';
                    i==1;
                    j+=1;
                    },
                'Т' => {
                    origin_mutated[i] = 'T';
                    i==1;
                    j+=1;
                    },
                'У' => {
                    origin_mutated[i] = 'U';
                    i+=1;
                    j+=1;
                    },
                'Ф' => {
                    origin_mutated[i] = 'F';
                    i==1;
                    j+=1;
                    },
                'Х' => {
                    origin_mutated[i] = 'K';
                    i+=1;
                    j==1;
                    origin_mutated[i] = 'h';
                    i+=1;
                    },
                'Ц' => {
                    origin_mutated[i] = 'T';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 's';
                    i+=1;
                    },
                'Ч' => {
                    origin_mutated[i] = 'C';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 'h';
                    i+=1;
                    },
                'Ш' => {
                    origin_mutated[i] = 'S';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 'h';
                    i+=1;
                    },
                'Щ' => {
                    origin_mutated[i] = 'S';
                    i+=1;
                    j==1;
                    origin_mutated[i] = 'h';
                    i+=1;
                    origin_mutated[i] = 'c';
                    i+=1;
                    origin_mutated[i] = 'h';
                    i+=1;
                    },
                'Ю' => {
                    origin_mutated[i] = 'Y';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 'u';
                    i+=1;
                    },
                'Я' => {
                    origin_mutated[i] = 'Y';
                    i+=1;
                    j+=1;
                    origin_mutated[i] = 'a';
                    i+=1;
                    },
                _ => {
                    j+=1;
                    }
                }
            }
        }
    else if j > counter{
        origin_mutated[i] = '\n'; 
    }
    else {
        origin = origin_mutated.into_iter().collect();
    }
    //origin = origin_mutated.into_iter().collect();
    (origin)
}

Upvotes: 5

Views: 4676

Answers (3)

Ibraheem Ahmed
Ibraheem Ahmed

Reputation: 13628

All stack variables in Rust are uninitialized until a value is explicitly assigned to them:

let mut origin_mutated: Vec<char>

Here, origin_mutated is not actually initialized as a vector. It it simply a placeholder for a vector that may or may not be initialized in the future.

Because Rust does not know if the variable was initialized, the compiler statically prevents you from reading it:

    |
188 |  origin_mutated[i] = 'Y';
    |  ^^^^^^^^^^^^^^ use of possibly-uninitialized `origin_mutated`

The solution is to initialize origin_mutated as an empty vector:

let mut origin_mutated: Vec<char> = Vec::new()

Upvotes: 0

AmigoNico
AmigoNico

Reputation: 6862

The reason for the error is that this line does NOT create a Vec:

let mut origin_mutated: Vec<char>;

It creates a variable which could hold a Vec, but doesn't yet, not even a zero-length one. It's like saying

let a: i32;

It doesn't have a value. You probably meant

let mut origin_mutated: Vec<char> = Vec::new();

Upvotes: 9

Louis Cloete
Louis Cloete

Reputation: 451

I'm not sure why your program doesn't compile, but even if it did compile, I think it'd probably panic when you try to index your origin_mutated vector. The reason is that your origin_mutated vec has a length of 0, so trying to index into it will panic according to the docs.

You can't index into an element of your vector which doesn't exist yet. You'd need to use a method like push() or similar to grow your Vec.

But there's an even better way to do this with Rust: by iterating over the input String and mapping over its elements:

pub fn transliterate(origin: &str) -> String {
    origin.chars().map(transliterate_letter).collect()
}

fn transliterate_letter(letter: char) -> &'static str {
    match letter {
        'А' => "A",
        'Б' => "B",
        ...
        'Є' => "Ye",
        ...
    }
}

Playground

Upvotes: 4

Related Questions