Я делаю аналог iostream C++ для ржавчины в последнее время, но запутаюсь в системе жизни. Я хочу сохранить ссылку читателя или голого читателя в 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
могут быть преобразованы вR
от derefrence. Так&mut D: DerefMut<R>
- потому что
&mut D
может быть разыменовываются кD
, но мне нужен&mut D
разыменовываются кR
, здесь необходимо использоватьtrait object
для динамической диспетчеризации методderef_mut
, из-за отсутствияUFCS
(трюк: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()
}
}
}
Было бы полезно, если бы вы могли сделать ваш пример как [меньшим, так и компилируемым] (http://stackoverflow.com/help/mcve). Если мы сможем вставить его в [playpen] (http://play.rust-lang.org/) и запустим его, чтобы увидеть вашу ошибку, тогда гораздо легче помочь. – Shepmaster