【发布时间】:2021-11-28 12:03:39
【问题描述】:
我正在努力用 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()。也许我需要忘记这一点?
【问题讨论】:
-
我在三个地方看到
'a:两个参数和一个返回值。你真的希望这三个生命周期都相同吗?您的算法中是否有理由必须这样做? -
不,但编译器也告诉了我。 :) 我相信因为来自
symbols和user_ops的元素都可以在返回值中结束。
标签: rust