繁体   English   中英

如何在 Rust 中使用递归 function 返回本地数据?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM