[英]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.