nom 和借用的价值没有足够长的时间错误

问题描述 投票:0回答:2

尝试与 nom 一起工作并迭代我的结果,但我无法弄清楚为什么这个借来的价值活得不够长。对 Rust 仍然是新手,并且已经思考了好几个小时。非常感谢帮助!

use anyhow;
use nom::{
    bytes::complete::{tag, take},
    character::complete::newline,
    combinator::rest,
    multi::separated_list1,
    sequence::separated_pair,
    IResult,
};

pub fn parse(raw: String) -> anyhow::Result<()> {
    let (_, lines) = parse_multiline(&raw)?;

    for line in lines.iter() {
        let (label, value) = line;

        println!("label: {}, value: {}", label, value);
    }

    Ok(())
}

fn parse_multiline(i: &str) -> IResult<&str, Vec<(&str, &str)>> {
    separated_list1(
        newline,
        separated_pair(
            take(14usize),
            tag(" : "),
            rest,
        ),
    )(i)
}

错误:

error[E0597]: `raw` does not live long enough
  --> src/parser/person.rs:12:38
   |
12 |     let (_, lines) = parse_multiline(&raw)?;
   |                      ----------------^^^^-
   |                      |               |
   |                      |               borrowed value does not live long enough
   |                      argument requires that `raw` is borrowed for `'static`
...
21 | }
   | - `raw` dropped here while still borrowed
rust parser-combinators nom
2个回答
3
投票

parse_multiline()
你返回
IResult<&str, Vec<(&str, &str)>>
。这意味着如果你的
parse_multiline()
失败,那么它返回
nom::Err
<
nom::error::Error
<&str>>
引用了
i
/
&raw

因此在

parse()
中,
parse_multiline(raw)?
进一步传播该错误,这将返回对
raw
的引用,它不会存活足够长的时间。


如果你想保留

fn parse(raw: String)
,那么你可以使用
Result::map_err()
,然后使用
nom::Err::map()
,在错误时将
&str
转换为拥有的
String

// nom = "6.1"
use nom::error::Error;

pub fn parse(raw: String) -> anyhow::Result<()> {
    let (_, lines) = parse_multiline(&raw)
        .map_err(|err| err.map(|err| Error::new(err.input.to_string(), err.code)))?;

    // ...
}

0
投票

@vallentin 的回答很棒。而对于 nom v7,有一个更短的版本

// nom = "7"
use nom::error::Error;

pub fn parse(raw: String) -> anyhow::Result<()> {
    let (_, lines) = parse_multiline(&raw)
        .map_err(|err| err.to_owned())?;

    // ...
}

© www.soinside.com 2019 - 2024. All rights reserved.