【发布时间】:2015-01-01 15:27:02
【问题描述】:
我最近正在为 rust 制作 c++ 的 iostream 的模拟,但被生命周期系统弄糊涂了。
我想在IStream 中存储读者或裸读者的引用,所以我在结构中存储了Q。而且我使用幻象类型D 将Q 转换为R。
解释如下:
-
R是我真正需要的Reader。 -
Q是R的存储类型,所以Q可能是一个裸露的R或引用&mut R。 - 我使用
D将Q转换为R。因为borrow_from_mut(&mut R)给了我一个&mut R,而borrow_from_mut(R)也给了我一个&mut R。因此它可能是D: BorrowFromMut<Q>。 - 和
D可以通过 derefence 转换为R。所以&mut D: DerefMut<R> - 因为
&mut D可以解引用到D,但是我需要&mut D解引用到R,这里必须使用trait object来动态调度deref_mut方法,因为没有@ 987654352@.(绝招:let tmp: &'c mut Q = &mut *self.istream.borrow_mut();)
这样的技巧使IStream 能够同时存储&mut R 和R。
但由于生命周期问题,代码无法编译:
let tmp: &'c mut Q = &mut *self.istream.borrow_mut();
//the Q borrowed from the RefCell only valid in the block, doesn't out live 'c.
我该如何解决?
这里是代码示例:
pub struct IStream<'a,'b,R:'a+'b,Q:'a+'b,Sized? D:'b> where R: Reader, D: BorrowFromMut<Q>, &'b mut D: DerefMut<R> {
istream: Rc<RefCell<Q>>
}
impl<'a,'b,R,Q,D> Clone for IStream<'a,'b,R,Q,D> where R: Reader, D: BorrowFromMut<Q>, &'b mut D: DerefMut<R> {
fn clone(&self) -> IStream<'a,'b,R,Q,D> {
IStream {
istream: self.istream.clone()
}
}
}
impl<'a,'b,'c,F,R,Q,D> Shr<&'b mut F,IStream<'a,'c,R,Q,D>> for IStream<'a,'c,R,Q,D> where R: Reader, F: FromStr + Default, D: BorrowFromMut<Q>, &'c mut D: DerefMut<R> {
fn shr(mut self, output: &mut F) -> IStream<'a,'c,R,Q,D> {
let tmp: &'c mut Q = &mut *self.istream.borrow_mut();
let mut reader: &mut D = BorrowFromMut::borrow_from_mut(tmp);
let mut real_reader: &DerefMut<R> = &reader;
let mut buf = String::new(); // a string buffer
loop {
if let Ok(byte) = (*real_reader.deref_mut()).read_byte() {
if byte == '\u{A}' as u8 || byte == '\u{20}' as u8 {
break
} else {
buf.push(byte as char);
}
} else {
break
}
}
*output = FromStr::from_str(buf[]).unwrap_or_default();
IStream {
istream: self.istream.clone()
}
}
}
【问题讨论】:
-
如果您可以同时将您的示例设为smaller and compilable,那将会很有用。如果我们可以将其粘贴到playpen 并运行它以查看您的错误,那么帮助会容易得多。
标签: rust type-systems lifetime