Rust 如何使用防锈型系统防止输出到标准装置?

Rust 如何使用防锈型系统防止输出到标准装置?,rust,locking,lifetime,borrow-checker,borrowing,Rust,Locking,Lifetime,Borrow Checker,Borrowing,我正在开发一个数据管道节点,这是一个应用程序,它从stdin连续提供数据,对其进行处理,并以流式方式将结果连续输出到stdout 考虑到数据交换格式是预先确定的,我需要一种简便的方法来阻止调试输出同时馈送到标准输出。本质上,是一个全局锁。没错,我可以去掉所有的调试语句,但这更像是一个学术练习 因此,让我们创建一个函数,该函数可以写入stdout,并锁定stdout,只要它保持在范围内,那么类型系统本身就可以防止代码中的其他位置写入stdout: use std::io::{self, Write

我正在开发一个数据管道节点,这是一个应用程序,它从
stdin
连续提供数据,对其进行处理,并以流式方式将结果连续输出到
stdout

考虑到数据交换格式是预先确定的,我需要一种简便的方法来阻止调试输出同时馈送到标准输出。本质上,是一个全局锁。没错,我可以去掉所有的调试语句,但这更像是一个学术练习

因此,让我们创建一个函数,该函数可以写入
stdout
,并锁定
stdout
,只要它保持在范围内,那么类型系统本身就可以防止代码中的其他位置写入
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(())
    }
}
我已经尝试了一个多小时来修复这7行代码中的借用检查器错误序列。以下是我迄今为止所采取的尚未奏效的步骤的非详尽列表:

  • 更改
    make_push_输出的生存期
  • 将显式类型和生存期注释添加到
    句柄
  • io::stdout()
    声明一个变量,并用类型和生存期进行注释
  • 向闭包添加显式类型和生存期注释
  • 声明本地函数而不是使用闭包,无法捕获环境
  • 在闭包上使用
    move
    语义,这不是最聪明的动作,但我在抓救命稻草

    • 你不能。标准输出锁是:

      这张照片是:

      句柄:1
      调试输出
      手柄:2
      
      < P>没有任何类型的杂耍可以防止同一线程重新获取锁到标准输出/错误,并在输出中间打印。


      您的编译器错误通过以下方式解决:

      • 返回一个
        &impl…
      • 正在尝试返回标准输出及其锁

      不管您遇到什么错误,将句柄锁定到标准输出实际上并不会给您带来任何好处——它只会锁定这个特定的句柄。您可以轻松地创建和使用不同的句柄,即使您持有的句柄已锁定。因此,理论上的选择是将stdout锁定在不同的线程中,并将所有所需的输出推送到队列,然后由持有锁的线程打印到stdout。但是,一旦主线程尝试使用
      println,就会导致死锁!()
      @SvenMarnach,使用类型系统解决问题在技术上仍然不能满足OPs要求,因为AFAICT Rust的类型系统根本不足以提供这种限制。
      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)
      }