所以我得到了这个小小的解析器,我有一些美好的时间来写它。但是我听说堆分配是魔鬼(或多或少),它可能被夸大了漫画效果。
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 _ => ~""
...
通过~
使用堆分配不是我的目标。我已经可以实现这一点。
因此可以使用借用检查器来允许:
Lex
提供的Buffer
构建Parse
的构造函数? Transfer
借用从Lex
提取的数据到Parse
?答案 0 :(得分:2)
Lex.make
:问题在于您通过值获取R
。也就是说,你正在消费它。在函数结束时,它被释放。因此,对它的引用无效。您需要做的是取&'a R
而不是R
作为参数。
Lex.results
:read_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() {
}