web*_*rts 1 stdin stdout lifetime rust
我正在建立一个PromptSet可以连续问一系列问题的人.出于测试原因,它允许您传递读写器而不是直接使用stdin和stdout.
因为stdin和stdout是常见的用例,所以我想创建一个默认的"构造函数",允许用户生成一个PromptSet<StdinLock, StdoutLock>不需要任何参数.这是迄今为止的代码:
use std::io::{self, BufRead, StdinLock, StdoutLock, Write};
pub struct PromptSet<R, W>
where
R: BufRead,
W: Write,
{
pub reader: R,
pub writer: W,
}
impl<R, W> PromptSet<R, W>
where
R: BufRead,
W: Write,
{
pub fn new(reader: R, writer: W) -> PromptSet<R, W> {
return PromptSet {
reader: reader,
writer: writer,
};
}
pub fn default<'a>() -> PromptSet<StdinLock<'a>, StdoutLock<'a>> {
let stdin = io::stdin();
let stdout = io::stdout();
return PromptSet {
reader: stdin.lock(),
writer: stdout.lock(),
};
}
pub fn prompt(&mut self, question: &str) -> String {
let mut input = String::new();
write!(self.writer, "{}: ", question).unwrap();
self.writer.flush().unwrap();
self.reader.read_line(&mut input).unwrap();
return input.trim().to_string();
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
StdinLock并且StdoutLock都需要终生宣布.为了使它复杂化,我认为原始stdin()/ stdout()句柄需要至少与锁一样长.我希望参考StdinLock和StdoutLock生活只要我PromptSet做,但无论我尝试什么,我都无法让它工作.这是我一直得到的错误:
error[E0597]: `stdin` does not live long enough
--> src/main.rs:30:21
|
30 | reader: stdin.lock(),
| ^^^^^ borrowed value does not live long enough
...
33 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the method body at 25:5...
--> src/main.rs:25:5
|
25 | / pub fn default<'a>() -> PromptSet<StdinLock<'a>, StdoutLock<'a>> {
26 | | let stdin = io::stdin();
27 | | let stdout = io::stdout();
28 | |
... |
32 | | };
33 | | }
| |_____^
error[E0597]: `stdout` does not live long enough
--> src/main.rs:31:21
|
31 | writer: stdout.lock(),
| ^^^^^^ borrowed value does not live long enough
32 | };
33 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the method body at 25:5...
--> src/main.rs:25:5
|
25 | / pub fn default<'a>() -> PromptSet<StdinLock<'a>, StdoutLock<'a>> {
26 | | let stdin = io::stdin();
27 | | let stdout = io::stdout();
28 | |
... |
32 | | };
33 | | }
| |_____^
Run Code Online (Sandbox Code Playgroud)
我完全有可能不理解生命的概念或其他超基本的概念.
该lock方法的签名是fn lock(&self) -> StdinLock,当使用生命周期注释完全展开时,是fn lock<'a>(&'a self) -> StdinLock<'a>.因此,StdinLock只有lock调用方法的值才能生存.既然你stdin在这个函数中定义了,StdinLock就不能比这个函数活得更久了.这与返回对本地值的引用相同.您也无法将引用和引用的值一起返回.
你不能这样做,你不能解决它.唯一的解决default方法是让方法将a Stdin和Stdout对象作为参数.
也就是说,你可以解决它.是的,我知道,我只是说完全相反,但更多的是"除了我以外没有人会使用stdin/stdout" (又名,println!不再适用了!).
在Rust 1.26中,您可以使用Box::leak泄漏Stdin到a &'static Stdin,这将产生一个StdinLock<'static>.在Rust 1.26之前,您可以使用leak包:
pub fn default() -> PromptSet<StdinLock<'static>, 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(),
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1046 次 |
| 最近记录: |