簡體   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