[英]How do I return local data with a recursive function in Rust?
我正在努力在 Rust 中編寫遞歸算法。 使用以下代碼:
use std::collections::HashMap;
enum Error {
Bad,
ReallyBad,
}
fn expand_symbols<'a, T: AsRef<str>>(
symbols: &'a [T],
ops: &HashMap<String, String>,
user_ops: &'a HashMap<String, String>,
) -> std::result::Result<Vec<&'a str>, Error> {
if symbols.iter().all(|x| ops.get(x.as_ref()).is_some()) {
let symbols = symbols.iter().map(|x| x.as_ref()).collect();
return Ok(symbols);
}
let mut expanded: Vec<&str> = vec![];
for s in symbols {
let s = s.as_ref();
if ops.contains_key(s) || s.parse::<i32>().is_ok() {
expanded.push(s);
} else {
let mut resolved = user_ops
.get(s)
.ok_or(Error::Bad)?
.split_ascii_whitespace()
.collect::<Vec<_>>();
expanded.append(&mut resolved);
}
}
expand_symbols(&expanded, ops, user_ops)
}
我得到:
error[E0515]: cannot return value referencing local variable `expanded`
--> src/main.rs:32:5
|
32 | expand_symbols(&expanded, ops, user_ops)
| ^^^^^^^^^^^^^^^---------^^^^^^^^^^^^^^^^
| | |
| | `expanded` is borrowed here
| returns a value referencing data owned by the current function
For more information about this error, try `rustc --explain E0515`.
但是,如果我將最后一條語句更改為:
Ok(expanded)
它有效,但不再是遞歸的。
我理解我試圖返回從本地框架借來的值的想法,但我認為基於第二個示例這是安全的。 我怎么能告訴編譯器呢?
注意:我使用AsRef
是因為我希望能夠將Vec<String>
和Vec<&str>
都傳遞給expand_symbols()
。 也許我需要忘記這一點?
使用Ok(expanded)
expanded
變量 expand 移出 function,這意味着在 function 返回后不存在對它的引用。 因此,如果您指的是Ok(expanded)
,則第二個示例與原始示例不同。
為了解決這個問題,我認為您可以傳遞對symbols
的可變引用作為 function 的第一個參數,並對其進行就地編輯,而不是創建一個新的局部向量, explanded
。
fn expand_symbols<'a>(
symbols: &'a mut Vec<&'a str>,
ops: &HashMap<String, String>,
user_ops: &'a HashMap<String, String>,
) -> std::result::Result<&'a Vec<&'a str>, Error> {
if symbols.is_empty() || symbols.iter().all(|x| ops.get(*x).is_some()) {
return Ok(symbols);
}
let mut unresolved: Vec<&str> = vec![];
let mut i = 0;
while i < symbols.len() {
let s = symbols[i];
if ops.contains_key(s) || s.parse::<i32>().is_ok() {
i += 1;
} else {
unresolved.push(symbols.remove(i));
}
}
for s in unresolved.iter() {
let mut resolved = user_ops
.get(*s)
.ok_or(Error::Bad)?
.split_ascii_whitespace()
.collect::<Vec<_>>();
symbols.append(&mut resolved);
};
expand_symbols(symbols, ops, user_ops)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.