首页 文章

无法摆脱借来的内容[E0507]

提问于
浏览
2

我正在写Rust的词法分析器来学习,但我坚持两个“不能摆脱借来的内容[E0507]”的错误 .

我尝试了所有解决方案,但似乎没有任何工作: RefCellclone()by_ref() ,将 &mut self 更改为 self&selfmut self ,或取消引用 .

这是我的代码:

struct Snapshot {
    Index: u32,
}

struct Tokenizable<'a, T: 'a>
    where T: Iterator
{
    Index: u32,
    Items: &'a T,
    Snapshots: Vec<Snapshot>,
}

impl<'a, T> Tokenizable<'a, T>
    where T: Iterator
{
    fn new(items: &'a T) -> Tokenizable<'a, T> {
        Tokenizable {
            Index: 0,
            Items: items,
            Snapshots: Vec::new(),
        }
    }

    fn end(&mut self) -> bool {
        match self.Items.peekable().peek() {
            Some(c) => false,
            None => true,
        }
    }

    fn peek(&mut self) -> Option<&T::Item> {
        match self.Items.peekable().peek() {
            Some(c) => Some(c),
            None => None,
        }
    }
}

fn main() {}
error: cannot move out of borrowed content [E0507]
         match self.Items.peekable().peek() {
               ^~~~~~~~~~
help: see the detailed explanation for E0507

error: borrowed value does not live long enough
         match self.Items.peekable().peek() {
               ^~~~~~~~~~~~~~~~~~~~~
note: reference must be valid for the anonymous lifetime #1 defined on the block at 32:43...
     fn peek(&mut self) -> Option<&T::Item> {
         match self.Items.peekable().peek() {
             Some(c) => Some(c),
             None => None,
         }
     }
note: ...but borrowed value is only valid for the block at 32:43
     fn peek(&mut self) -> Option<&T::Item> {
         match self.Items.peekable().peek() {
             Some(c) => Some(c),
             None => None,
         }
     }

error: cannot move out of borrowed content [E0507]
         match self.Items.peekable().peek() {
               ^~~~~~~~~~
help: see the detailed explanation for E0507

2 回答

  • 3

    正如您在docs中看到的那样, peekable 函数按值获取迭代器 . 因此,只有拥有迭代器才能工作 . 但是,在您的代码中, Items 是迭代器的共享引用 .

    解决这个问题需要从不同的角度接近它 . 例如,您可以在构造函数中按值获取迭代器,并调整struct以在 Items 字段中存储peekable迭代器 .

  • 1

    基本上,从这里可以学到的是,过度复杂化和过度工程化的事情几乎总是弊大于利 .

    最终固定代码:

    use std::iter::Peekable;
    
    struct Snapshot {
        index: u32
    }
    
    struct Tokenizable<T> where T: Iterator {
        index : u32,
        items : Peekable<T>,
        snapshots : Vec<Snapshot>,
    }
    
    impl<T> Tokenizable<T> where T: Iterator {
        fn new (items: T) -> Tokenizable<T>  {
            Tokenizable {
                index : 0,
                items : items.peekable (),
                snapshots : Vec::new (),
            }
        }
    
        fn end (&mut self) -> bool {
            match self.items.peek () {
                Some (c) => false,
                None => true
            }
        }
    
        fn peek (&mut self) -> Option<&<T as Iterator>::Item> {
            match self.items.peek () {
                Some (c) => Some (c),
                None => None
            }
        }
    }
    
    fn main () {
        let mut data = "Hello".chars ();
        let tokenizable = Tokenizable::new (data);
    }
    

相关问题