文本文件解析功能由于生命周期/借用错误而无法编译 [英] Textfile-parsing function fails to compile owing to lifetime/borrow error

查看:75
本文介绍了文本文件解析功能由于生命周期/借用错误而无法编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

NB.该帖子最初是一个较大的帖子的一部分,该帖子包含两个问题(我认为这是一个错误地表示了自己的错误),但是为了遵守站点准则,我将其分为两个单独的帖子,这是第二个帖子.第一篇文章是此处.

NB. This post was originally part of a larger post that contained two questions (that I'd believed were one error manifesting itself differently), but to comply with site guidelines I've split it into two separate posts, of which this is the second. The first post is here.

我正在尝试解析一个简单的配置文本文件,该文件每行包含一个三个单词的条目,布局如下:

I'm trying to parse a simple config text file, which contains one three-word entry per line, laid out as follows:

ITEM name value
ITEM name value
//etc.

我已经在此处复制了进行解析(以及随后的编译错误)的函数(并且在Rust操场上):

I've reproduced the function which does the parsing (and the subsequent compilation error) here (and on the Rust playground):

use std::fs::File;
use std::io::prelude::*;
use std::io::BufReader;
use std::path::Path;
use std::collections::HashMap;

fn main() { }

pub fn parse(path: &Path) -> config_struct {

    let file = File::open(&path).unwrap();
    let reader = BufReader::new(&file);
    let line_iterator = reader.lines();
    let mut connection_map = HashMap::new();
    let mut target_map = HashMap::new();

    for line in line_iterator {

        let line_slice = line.unwrap();
        let word_vector: Vec<&str> = line_slice.split_whitespace().collect();

        if word_vector.len() != 3 { continue; }

        // no match statement   
        connection_map.insert(word_vector[1], word_vector[2]);
    }

    config_struct { connections: connection_map, targets: target_map }
}

pub struct config_struct<'a>  {
    // <name, value>
    connections: HashMap<&'a str, &'a str>,
    // <name, value>
    targets: HashMap<&'a str, &'a str>,
}

<anon>:20:38: 20:48 error: `line_slice` does not live long enough
<anon>:20         let word_vector: Vec<&str> = line_slice.split_whitespace().collect();
                                               ^~~~~~~~~~
note: in expansion of for loop expansion
<anon>:17:5: 26:6 note: expansion site
<anon>:9:44: 29:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 9:43...
<anon>:9 pub fn parse(path: &Path) -> config_struct {
<anon>:10 
<anon>:11     let file = File::open(&path).unwrap();
<anon>:12     let reader = BufReader::new(&file);
<anon>:13     let line_iterator = reader.lines();
<anon>:14     let mut connection_map = HashMap::new();
          ...
<anon>:19:40: 26:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 19:39
<anon>:19         let line_slice = line.unwrap();
<anon>:20         let word_vector: Vec<&str> = line_slice.split_whitespace().collect();
<anon>:21 
<anon>:22         if word_vector.len() != 3 { continue; }
<anon>:23 
<anon>:24         // no match statement   
          ...
error: aborting due to previous error

从本质上讲,我在借阅检查器方面遇到了麻烦;在我的代码中,word_vector不会填充没有指向line_slice的自有对象吗?我认为unwrap()collect()可能返回了引用,并且该引用超出了范围,但是

In essence, I am having trouble with the borrow-checker; in my code, isn't word_vector populated with owned objects that don't point to line_slice? I figured that perhaps unwrap() or collect() returned a reference and that it was the reference that was going out of scope, but the Rust Docs for unwrap and collect suggest otherwise.

推荐答案

&str在没有存储其包含的值的情况下无法存在-它纯粹是一个引用(因此为&).

A &str cannot exist without something storing the value it contains—it is purely a reference (hence the &).

从文件中读取String这些提供存储空间.但是您要删除它们,尝试仅返回字符串.

Reading from the file you get Strings; these provide the storage. But you are dropping them, trying to only return the strings.

也这样想:

pub fn parse(path: &Path) -> config_struct<'???>;

您应该为返回值设置哪个生存期?

What lifetime should you have for the return value?

它不抱怨该部分的唯一原因是,它推断出Path的引用生存期和返回值生存期是相同的,这意味着您正在返回对Path内部内容的引用. ,但您不是.

The only reason it didn’t complain of that part is that it inferred that the Path reference lifetime and the return value lifetime were the same, which would imply that you are returning a reference to something inside the Path, which you are not.

在这种情况下,通常需要存储String而不是&str.用.to_owned()将每个&str转换为String.

In such a situation as this, you typically need to store Strings instead of &strs. Convert each &str to a String with .to_owned().

这篇关于文本文件解析功能由于生命周期/借用错误而无法编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆