match运算符可能借用了未初始化的变量



我正在设计一个库,可以将给定的字符串从乌克兰语音译为英语,所以我决定使用"match"运算符来定义语句,并检查多个条件。但我遇到了编译器错误,这是Rust的典型错误,但在我的情况下是完全不可能的(至少我认为是这样(。


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

这是一个库的完整代码。如果我没有看到明显的东西(因为我怀疑这可能是编译器中的错误(,请让我的鼻子碰到一个问题。

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)
}

错误的原因是此行没有创建Vec:

let mut origin_mutated: Vec<char>;

它创建了一个变量,可以保存Vec,但还没有,甚至不是零长度的Vec。这就像说

let a: i32;

它没有价值。你可能是指

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

我不知道为什么你的程序没有编译,但即使它编译了,我认为当你试图索引origin_mutated向量时,它可能会死机。原因是origin_mutatedvec的长度为0,因此根据文档,试图对其进行索引会引起恐慌。

你不能索引到你的向量中一个还不存在的元素。您需要使用类似push()或类似的方法来增长您的Vec

但使用Rust还有一种更好的方法:通过对输入String进行迭代,并对其元素进行mapping:

pub fn transliterate(origin: &str) -> String {
origin.chars().map(transliterate_letter).collect()
}
fn transliterate_letter(letter: char) -> &'static str {
match letter {
'А' => "A",
'Б' => "B",
...
'Є' => "Ye",
...
}
}

游乐场

Rust中的所有堆栈变量都未初始化,直到显式为它们赋值:

let mut origin_mutated: Vec<char>

这里,origin_mutated实际上并没有被初始化为向量。它只是一个矢量的占位符,将来可能会初始化,也可能不会初始化。

因为Rust不知道变量是否已初始化,所以编译器静态地阻止您读取它:

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

解决方案是将origin_mutated初始化为空向量:

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

最新更新