2017-05-28 81 views
-1

重構此解析器代碼以避免借用檢查問題的最佳方法是什麼?重構解析器代碼以避免借用檢查問題

pub type Token=u8; 
pub trait Stream { 
    type Item; 
    fn next(&mut self) -> Option<&Self::Item>; 
    fn peek(&mut self) -> Option<&Self::Item>; 
} 

#[derive(Clone)] 
pub struct Parser { 
    input: Vec<Token>, 
    position: usize, 
} 

pub type ParseError = String; 
pub type ParseResult<T> = Result<T, ParseError>; 

impl Stream for Parser { 
    type Item = Token; 

    fn next(&mut self) -> Option<&Token> { 
     let token = self.input.get(self.position); 
     self.position += 1; 
     token 
    } 

    fn peek(&mut self) -> Option<&Token> { 
     self.input.get(self.position + 1) 
    } 
} 

fn parse_expr(stream: &mut Parser) -> ParseResult<()> { 
    match stream.peek() { // ~~ borrowed stream here 
     None => Err(String::from("No more tokens")), 
     Some(t) => match t { 
      &0 => parse_number_literal(stream), // ~~ and here 
      &1 => panic!("parse string"), 
      &2 => panic!("parse character"), 
      _ => Err(String::from("Unexpected Token")), 
     } 
    } 
} 

fn parse_number_literal(stream: &mut Parser) -> ParseResult<()> { 
    let token = stream.next(); 
    Ok(()) 
} 

fn main(){} 

編譯器的投訴約cannot borrow *流as mutable more than once at a time。閱讀其他stackoverflow問題只回答爲什麼發生這個問題,但不是如何解決問題。

回答

1

您的peek功能不需要&mut self,只使用&self將完全解決您的錯誤,併爲您提供cannot borrow *stream as mutable because it is also borrowed as immutable。無論如何,避免mut不需要時更好。

你的問題是你綁定Token參考t,所以借款不會結束。你並不需要有一個多層次match,並且可以做同樣的事情

fn parse_expr(stream: &mut Parser) -> ParseResult<()> { 
    match stream.peek() { 
     None => Err(String::from("No more tokens")), 
     Some(&0) => parse_number_literal(stream), 
     Some(&1) => panic!("parse string"), 
     Some(&2) => panic!("parse character"), 
     _ => Err(String::from("Unexpected Token")), 
    } 
} 

或者你可以改變偷看

fn peek(&self) -> Option<Token> { 
    self.input.get(self.position + 1).cloned() 
} 

這不會產生借問題,但會克隆數據。

+0

謝謝。將代碼重構爲單一匹配。 –