rust 借货检查员:如何从可变结构体的不可变成员中不可变地借用?

8yparm6h  于 2023-01-21  发布在  其他
关注(0)|答案(1)|浏览(163)

在本例中:https://godbolt.org/z/qjnq31zsW

pub struct Parser<'a>  {
    pub tokens: &'a Vec<&'a str>,
    pub counter: usize
}


pub fn advance<'a>(p: &'a mut Parser) -> &'a str {
    p.counter += 1;
    p.tokens[p.counter-1]
}

pub fn build_expression<'a>(p: &'a mut Parser) -> Vec<&'a str>{

    let there = advance(p);
    let once = advance(p);
    let was = advance(p);

    vec![there, once, was]

}

fn main(){
    
    let sentence = "there once was a lady who swallowed a fly".to_string();
    
    let words = vec![ &sentence[0..5],
                      &sentence[6..10],
                      &sentence[11..14],
                      &sentence[15..16],
                      &sentence[17..21],
                      &sentence[22..25],
                      &sentence[26..35],
                      &sentence[36..37],
                      &sentence[38..41],
    ];
    
    println!("{:?}", words);

    let mut p = Parser{tokens:&words, counter:0};
    let expr = build_expression(&mut p);

    println!("{:?}", expr);

}

我有一个结构体,其中包含一些不可变的数据(单词/标记的列表),以及一些可变的数据(当前单词的计数器)。
当代码的另一部分借用一个单词/标记时,我如何说服借用检查器让我改变计数器

nx7onnlm

nx7onnlm1#

你可以告诉编译器你的引用不是从Parserp派生的,而是从它所引用的东西派生的。你可以通过把返回值&'a str链接到&mut Parser<'a>而不是&'a mut Parser来做到这一点:

pub fn advance<'a>(p: &mut Parser<'a>) -> &'a str {
    p.counter += 1;
    p.tokens[p.counter-1]
}

pub fn build_expression<'a>(p: &mut Parser<'a>) -> Vec<&'a str>{
    let there = advance(p);
    let once = advance(p);
    let was = advance(p);

    vec![there, once, was]
}

请看它在playground上的工作情况。
由于这些引用由不同的生存期支持,因此可以安全地将这些引用与解析器本身断开连接,这样解析器就不受这些引用的约束,并允许对它进行修改。

相关问题