2016-12-27 1 views
0

구조체에 바인딩되는 대신 문자열을 구문 분석 메서드에 전달할 수 있도록 파서를 다시 작성하려고합니다.파서 구조체의 수명이 느리다

이전에, 내 코드는 다음과 같이 보았다 :

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 반복자를 통해) 참조를 저장하려고했습니다. 두 수명은 서로 관련이 없으므로 수명이 오래 지속될 지 확신 할 수 없습니다.