Is there a way to use locked standard input and output in a constructor to live as long as the struct you're constructing?

后端 未结 2 1533
没有蜡笔的小新
没有蜡笔的小新 2021-01-21 12:36

I\'m building a PromptSet that can ask a series of questions in a row. For testing reasons, it allows you to pass a reader and writer instead of using stdin & s

2条回答
  •  旧时难觅i
    2021-01-21 13:18

    The lock method's signature is fn lock(&self) -> StdinLock, which, when fully expanded with lifetime annotations, is fn lock<'a>(&'a self) -> StdinLock<'a>. Thus the StdinLock can only live as long as the value that the lock method is called on. Since you defined stdin in this very function, the StdinLock can't outlive the function. This is the same as returning a reference to a local value. You also can't return the reference and the referred-to value together.

    You can't do this, and you can't work around it. The only fix is to have the default method take a Stdin and a Stdout object as arguments.

    That said, you can work around it. Yes I know, I just said the exact opposite, but it's more of a "no one other than me will ever use stdin/stdout" (a.k.a., println! will not work anymore!).

    In Rust 1.26, you can use Box::leak to leak the Stdin to a &'static Stdin, which will yield a StdinLock<'static>. Before Rust 1.26, you can use the leak crate:

    pub fn default() -> PromptSet, StdoutLock<'static>> {
        let stdin = Box::leak(Box::new(io::stdin()));
        let stdout = Box::leak(Box::new(io::stdout()));
    
        PromptSet {
            reader: stdin.lock(),
            writer: stdout.lock(),
        }
    }
    

提交回复
热议问题