Rust时间轴和所有权问题

时间:2019-05-25 15:12:37

标签: rust lifetime ownership

我正在尝试通过读取文件来创建哈希图。下面是我编写的代码。所不同的是,我需要坚持subset_description直到下一次迭代,以便可以将其存储在hasmap中,然后最终返回该哈希图。

fn myfunction(filename: &Path) -> io::Result<HashMap<&str, &str>> {
    let mut SIF = HashMap::new();
    let file = File::open(filename).unwrap();
    let mut subset_description = "";
    for line in BufReader::new(file).lines() {
        let thisline = line?;
        let line_split: Vec<&str> = thisline.split("=").collect();
        subset_description = if thisline.starts_with("a") {
            let subset_description = line_split[1].trim();
            subset_description
        } else {
            ""
        };
        let subset_ids = if thisline.starts_with("b") {
            let subset_ids = line_split[1].split(",");
            let subset_ids = subset_ids.map(|s| s.trim());
            subset_ids.collect()
        } else {
            Vec::new()
        };
        for k in subset_ids {
            SIF.insert(k, subset_description);
            println!("");
        }
        if thisline.starts_with("!dataset_table_begin") {
            break;
        }
    }
    Ok(SIF)
}

我遇到以下错误,无法解决此问题

error[E0515]: cannot return value referencing local variable `thisline`
  --> src/main.rs:73:5
   |
51 |         let line_split: Vec<&str> = thisline.split("=").collect();
   |                                     -------- `thisline` is borrowed here
...
73 |     Ok(SIF)
   |     ^^^^^^^ returns a value referencing data owned by the current function

1 个答案:

答案 0 :(得分:0)

问题出在Rust代表您做出的保证之内。问题的根源如下。您正在读取文件并将其内容处理到HashMap中,并且试图返回对所读取数据的引用。但是,通过返回引用,您需要保证文件中的字符串以后不会更改,而您自然不能这么做。

用Rust术语,您一直试图返回对局部变量的引用,这些引用在函数末尾被删除,这将有效地使您留下悬空的指针。这是我所做的更改,即使它们可能不是最有效的,也可以编译。

fn myfunction(filename: &Path) -> io::Result<HashMap<String, String>> {
    let mut SIF = HashMap::new();
    let file = File::open(filename).unwrap();
    let mut subset_description = "";
    for line in BufReader::new(file).lines() {
        let thisline = line?;
        let line_split: Vec<String> = thisline.split("=").map(|s| s.to_string()).collect();
        subset_description = if thisline.starts_with("a") {
            let subset_description = line_split[1].trim();
            subset_description
        } else {
            ""
        };
        let subset_ids = if thisline.starts_with("b") {
            let subset_ids = line_split[1].split(",");
            let subset_ids = subset_ids.map(|s| s.trim());
            subset_ids.map(|s| s.to_string()).collect()
        } else {
            Vec::new()
        };
        for k in subset_ids {
            SIF.insert(k, subset_description.to_string());
            println!("");
        }
        if thisline.starts_with("!dataset_table_begin") {
            break;
        }
    }
    Ok(SIF)
}

如您所见,现在您放弃了返回值中字符串的所有权。这可以通过修改返回类型并使用to_string()函数来实现,以将本地字符串的所有权分配给HashMap

有一个论点是to_string()的速度很慢,因此您可以探索对into或to_owned()的使用,但是由于我不精通这些结构,因此无法协助您进行优化。