2016-12-27 8 views
0

構造体にバインドされるのではなく、解析メソッドに文字列が渡されるようにパーサーを書き直そうとしています。Rustのパーサ構造体の存続期間

以前は、私のコードは次のように見えた:

use std::collections::HashMap; 
use std::str; 

#[derive(Debug)] 
pub enum ParserError { 
    Generic 
} 

pub struct Resource(
    pub HashMap<String, String> 
); 

pub struct Parser<'a> { 
    source: Option<str::Chars<'a>> 
} 

impl<'a> Parser<'a> { 
    pub fn new() -> Parser<'a> { 
     Parser { source: None } 
    } 
    pub fn parse(&mut self, source: &str) -> Result<Resource, ParserError> { 
     self.source = Some(source.chars()); 

     let entries = HashMap::new(); 
     Ok(Resource(entries)) 
    } 
} 

fn main() { 
    let parser = Parser::new(); 
    parser.parse("key1 = Value 1"); 
    parser.parse("key2 = Value 2"); 
} 

が、私は寿命をいじってるようには思わ:

use std::collections::HashMap; 
use std::str; 

#[derive(Debug)] 
pub enum ParserError { 
    Generic 
} 

pub struct Resource(
    pub HashMap<String, String> 
); 

pub struct Parser<'a> { 
    source: str::Chars<'a> 
} 

impl<'a> Parser<'a> { 
    pub fn new(source: &str) -> Parser { 
     Parser { source: source.chars() } 
    } 
    pub fn parse(&mut self) -> Result<Resource, ParserError> { 
     let entries = HashMap::new(); 
     Ok(Resource(entries)) 
    } 
} 

fn main() { 
    let parser = Parser::new("key1 = Value 1"); 
    let res = parser.parse(); 
} 

と私の新しいコードでは、私はこのような何かをしようとしている

私は完全に快適ではない方法です。私が得るエラーは次のとおりです:

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements 
    --> test.rs:22:35 
    | 
22 |   self.source = Some(source.chars()); 
    |  

これを処理する標準的な方法は何ですか? Stringを取得して、Parser構造体の寿命にどのようにクローンできますか?

答えて

1

完全なエラーメッセージがある:それが示唆するように

error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements 
    --> src/main.rs:22:35 
    | 
22 |   self.source = Some(source.chars()); 
    |         ^^^^^ 
    | 
help: consider using an explicit lifetime parameter as shown: fn parse(&mut self, source: &'a str) -> Result<Resource, ParserError> 
    --> src/main.rs:21:5 
    | 
21 |  pub fn parse(&mut self, source: &str) -> Result<Resource, ParserError> { 
    | ^

はアウトドア:

pub fn parse(&mut self, source: &'a str) -> Result<Resource, ParserError> 

コードが(mainに無関係ミスマッチ可変性を修正した後に)コンパイルして実行することができます。


違いを理解するには、まずlifetime elisionを理解する必要があります。

あなたのオリジナルのコードがあった。すなわち

fn new(source: &str) -> Parser // with elision 
fn new<'b>(source: &'b str) -> Parser<'b> // without elision 

、構造体の一般的な寿命パラメータ'aが入ってくる文字列の寿命に結びつきました。

あなたの新しいコードはもっと複雑だった:すなわち

fn new() -> Parser<'b> 

// with elision 
fn parse(&mut self, source: &str) -> Result<Resource, ParserError> 
// without elision 
fn parse<'c, 'd>(&'c mut self, source: &'d str) -> Result<Resource, ParserError> 

、構造体の一般的な寿命パラメータ'aはまだnewの呼び出し元によって定義されていますが、今では、コンストラクタから何にも縛られていません。 parseを呼び出すと、無関係のライフタイムの文字列を渡して、それに参照を格納しようとしていました(Charsイテレータを使用)。 2つの生涯は無関係だったので、あなたはそれが十分長く続くことを確かめることはできません。

関連する問題