我正在研究数据流水线节点,该应用程序从stdin
连续获取数据,进行处理,然后以流方式将结果连续输出到stdout
。
考虑到数据交换格式是预先确定的,我需要一种方便的方法来禁止调试输出同时馈入到stdout。本质上是全局锁定。没错,我可以摆脱所有调试语句,但这更多是学术性的练习。
因此,让我们创建一个可以写入stdout
并锁定stdout
的函数,只要它保留在范围内,这样类型系统本身就可以防止代码中的其他位置写入{ {1}} :
stdout
很酷,use std::io::{self, Write};
pub fn make_push_output<'a>() -> &'a impl Fn(String) -> io::Result<()> {
let handle = io::stdout().lock();
&|output: String| {
handle.write(output.to_string().as_bytes())?;
Ok(())
}
}
上的全局锁一直保持到输出stdout
函数的作用域超出作用域之前,但是不会起作用。我得到了借用检查器错误的完整列表:
push_output()
我已经尝试了一个多小时,以解决这7行代码中的借位检查器错误序列。这是到目前为止我没有采取的步骤的详尽列表:
error[E0597]: borrowed value does not live long enough
--> src/lib.rs:4:18
|
4 | let handle = io::stdout().lock();
| ^^^^^^^^^^^^ - temporary value only lives until here
| |
| temporary value does not live long enough
|
= note: borrowed value must be valid for the static lifetime...
error[E0597]: borrowed value does not live long enough
--> src/lib.rs:6:6
|
6 | &|output: String| {
| ______^
7 | | handle.write(output.to_string().as_bytes())?;
8 | |
9 | | Ok(())
10 | | }
| |_____^ temporary value does not live long enough
11 | }
| - temporary value only lives until here
|
note: borrowed value must be valid for the lifetime 'a as defined on the function body at 3:25...
--> src/lib.rs:3:25
|
3 | pub fn make_push_output<'a>() -> &'a impl Fn(String) -> io::Result<()> {
| ^^
error[E0373]: closure may outlive the current function, but it borrows `handle`, which is owned by the current function
--> src/lib.rs:6:6
|
6 | &|output: String| {
| ^^^^^^^^^^^^^^^^ may outlive borrowed value `handle`
7 | handle.write(output.to_string().as_bytes())?;
| ------ `handle` is borrowed here
help: to force the closure to take ownership of `handle` (and any other referenced variables), use the `move` keyword
|
6 | &move |output: String| {
| ^^^^^^^^^^^^^^^^^^^^^
error[E0387]: cannot borrow data mutably in a captured outer variable in an `Fn` closure
--> src/lib.rs:7:9
|
7 | handle.write(output.to_string().as_bytes())?;
| ^^^^^^
|
help: consider changing this closure to take self by mutable reference
--> src/lib.rs:6:6
|
6 | &|output: String| {
| ______^
7 | | handle.write(output.to_string().as_bytes())?;
8 | |
9 | | Ok(())
10| | }
| |_____^
的生存期make_push_output
添加显式类型和生存期批注handle
声明一个变量,并使用类型和生存期进行注释io::stdout()
语义,不是最明智的举动,但我正在抓住稻草答案 0 :(得分:3)
您不能。标准输出锁定为reentrant:
use std::io::{self, Write};
fn main() {
let out = io::stdout();
let mut handle = out.lock();
writeln!(handle, "handle: {}", 1);
println!("Debugging output");
writeln!(handle, "handle: {}", 2);
drop(handle)
}
此打印:
handle: 1
Debugging output
handle: 2
没有任何类型的杂耍可以阻止同一线程重新获得对标准输出/错误的锁定并在输出的中间进行打印。
您的编译器错误的解决方法:
& impl ...
stdout
及其锁定