簡體   English   中英

銹:一生的問題,需要幫助

[英]rust: lifetime issue, need a hand

我最近正在模擬c ++的iostream進行銹蝕,但是對生命周期系統感到困惑。 我想在IStream存儲閱讀器或裸閱讀器的引用,因此我在結構中存儲了Q 然后我使用幻影類型DQ轉換為R

這里是解釋:

  • R是我真正需要的Reader
  • QR的商店類型,因此Q可能是裸R或引用&mut R
  • 我用DQ轉換為R 因為borrow_from_mut(&mut R)給了我&mut R ,而borrow_from_mut(R)也給了我&mut R borrow_from_mut(R) 因此它可能是D: BorrowFromMut<Q>
  • D可以通過反折射轉換為R 所以&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 RR

但是由於存在生命周期問題,因此無法編譯代碼:

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()
        }
    }
}

我認為您正試圖超越自己。 您不需要同時存儲閱讀器或對閱讀器的可變引用,因為您可以輕松地將此類可變引用轉換為完整的閱讀器。 沒有這些復雜性,您的代碼將如下所示(請注意下面的by_ref()示例):

#![feature(slicing_syntax)]

use std::cell::RefCell;
use std::rc::Rc;
use std::str::FromStr;
use std::default::Default;
use std::io::ByRefReader;

pub struct IStream<R> where R: Reader {
    istream: Rc<RefCell<R>>
}

impl<R> Clone for IStream<R> where R: Reader {
    fn clone(&self) -> IStream<R> {
        IStream {
            istream: self.istream.clone()
        }
    }
}

impl<'b, F, R> Shr<&'b mut F, IStream<R>> for IStream<R> where R: Reader, F: FromStr + Default {
    fn shr(self, output: &'b mut F) -> IStream<R> {  // '
        let mut real_reader = self.istream.borrow_mut();

        let mut buf = String::new(); // a string buffer
        loop {
            if let Ok(byte) = real_reader.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();

        self.clone()
    }
}

fn main() {
    let mut stdin = std::io::stdin();
    let stdin_ref: &mut _ = &mut stdin;  // a mutable reference to a reader

    let is = IStream { istream: Rc::new(RefCell::new(stdin_ref.by_ref())) };

    let mut x: uint = 0;
    let mut y: uint = 0;

    is >> &mut x >> &mut y;

    println!("{}, {}", x, y);
}

這是您提到的錯誤的再現:

use std::cell::RefCell;

fn foo<'a>(rc: &'a RefCell<u8>) { 
    let b: &'a u8 = &*rc.borrow();
}

fn main() {
}

這無法編譯

借來的價值壽命不長

根據定義, borrow()的結果的作用域與其調用的作用域綁定在一起,您不能通過指定其他生存期來“欺騙”它。 所有要做的就是使編譯器告訴您不能這樣做。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM