借用检查值进出结构域?

时间:2014-03-05 21:05:18

标签: memory-management rust

所以我得到了这个小小的解析器,我有一些美好的时间来写它。但是我听说堆分配是魔鬼(或多或少),它可能被夸大了漫画效果。

example.rs

pub struct Parse<'a, R> {
    slave: Lex<'a, R>
}

enum Transfer<'a> {
    Result(&'a str)
}

pub struct Lex <'a, R> {
    src:&'a R
}

impl<'a,R:Buffer> Lex<'a, R> {
    pub fn make(src : R) -> Lex<'a, R> {
        Lex {
            src: &'a src
        }
    }

    pub fn results(&mut self) -> Transfer<'a> {
        let line = match self.src.read_line() {
            Ok(line) => {
                line
            },
            _ => ~""
        };
        let brw = line.as_slice();
        Result(brw)
    }
}

fn main() {

}

编译因以下错误而失败:

example.rs:16:18: 16:25 error: `src` does not live long enough
example.rs:16             src: &'a src
                               ^~~~~~~
example.rs:14:40: 18:6 note: reference must be valid for the lifetime &'a  as defined on the block at 14:39...
example.rs:14     pub fn make(src : R) -> Lex<'a, R> {
example.rs:15         Lex {
example.rs:16             src: &'a src
example.rs:17         }
example.rs:18     }
example.rs:14:40: 18:6 note: ...but borrowed value is only valid for the block at 14:39
example.rs:14     pub fn make(src : R) -> Lex<'a, R> {
example.rs:15         Lex {
example.rs:16             src: &'a src
example.rs:17         }
example.rs:18     }
example.rs:21:26: 21:34 error: cannot borrow immutable dereference of `&`-pointer `*self.src` as mutable
example.rs:21         let line = match self.src.read_line() {
                                       ^~~~~~~~
example.rs:27:19: 27:23 error: `line` does not live long enough
example.rs:27         let brw = line.as_slice();
                                ^~~~
example.rs:20:47: 29:6 note: reference must be valid for the lifetime &'a  as defined on the block at 20:46...
example.rs:20     pub fn results(&mut self) -> Transfer<'a> {
example.rs:21         let line = match self.src.read_line() {
example.rs:22             Ok(line) => {
example.rs:23                 line
example.rs:24             },
example.rs:25             _ => ~""
              ...
example.rs:20:47: 29:6 note: ...but borrowed value is only valid for the block at 20:46
example.rs:20     pub fn results(&mut self) -> Transfer<'a> {
example.rs:21         let line = match self.src.read_line() {
example.rs:22             Ok(line) => {
example.rs:23                 line
example.rs:24             },
example.rs:25             _ => ~""
              ...

通过~使用堆分配不是我的目标。我已经可以实现这一点。

因此可以使用借用检查器来允许:

  1. 使用Lex提供的Buffer构建Parse的构造函数?
  2. 枚举Transfer借用从Lex提取的数据到Parse

1 个答案:

答案 0 :(得分:2)

Lex.make:问题在于您通过获取R。也就是说,你正在消费它。在函数结束时,它被释放。因此,对它的引用无效。您需要做的是取&'a R而不是R作为参数。

Lex.resultsread_line()返回Result<~str, IoError>。同样,对象(这次是~str)在方法中拥有,因此一旦到达方法的末尾,它将在超出范围时被释放。因此,您不能使用引用 - 您应该将~str传递给调用者,不会附带终生担忧。

这是最终的代码:

pub struct Parse<'a, R> {
    slave: Lex<'a, R>
}

enum Transfer {
    Result(~str)
}

pub struct Lex<'a, R> {
    src: &'a R
}

impl<'a, R: Buffer> Lex<'a, R> {
    pub fn make(src: &'a R) -> Lex<'a, R> {
        Lex {
            src: src
        }
    }

    pub fn results(&mut self) -> Transfer {
        let line = match self.src.read_line() {
            Ok(line) => line,
            _ => ~"",
        };
        Result(line)
    }
}

fn main() {
}