如何编写一个以“AlternateScreen”作为字段的结构?

How do I write a struct with an `AlternateScreen` as a field?

我正在编写一个小的 Rust 终端箱,我需要创建一个具有 screen 字段的结构,其中 screen 是一个 termion::AlternateScreen。这是我的代码:

use std::io::{stdout, Write};
use termion;
use termion::raw::IntoRawMode;
use termion::screen::*;

pub struct Window {
    screen: AlternateScreen,
    stdout: termion::raw::RawTerminal<std::io::Stdout>,
}
impl Window {
    
    /// Returns the completed [`Window`]; to be called after all the builder functions
    pub fn build(self) -> Window {
        Window { screen: self.screen, stdout: self.stdout }
    }

    /// Returns a new [`Window`], which can then be built using the builder functions
    pub fn builder() -> Window {
        Window { screen: AlternateScreen::from(stdout), stdout: stdout().into_raw_mode().unwrap(), }
    }
}

不幸的是,当我尝试编译它时,我收到一条错误消息:

error[E0107]: missing generics for struct `termion::screen::AlternateScreen`
  --> src/widgets.rs:11:13
   |
11 |     screen: AlternateScreen,
   |             ^^^^^^^^^^^^^^^ expected 1 generic argument
   |
note: struct defined here, with 1 generic parameter: `W`
  --> /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/termion-1.5.6/src/lib.rs:49:12
   |
49 | pub struct AlternateScreen<W: Write> {
   |            ^^^^^^^^^^^^^^^ -
help: add missing generic argument
   |
11 |     screen: AlternateScreen<W>,
   |             ~~~~~~~~~~~~~~~~~~

当我在其中添加 <W> 时,正如它所暗示的那样,我收到另一个错误,指出 W 未定义。当我通过将 <W> 添加到 pub struct Window 的末尾来修复该问题时,我收到一条错误消息,指出程序中 Window 的其他用途的 none 具有 <W>。当我修复所有 that(通过将 <W> 添加到代码中每个 Window 的末尾)时,我收到另一条错误消息:

error[E0277]: the trait bound `W: std::io::Write` is not satisfied
  --> src/widgets.rs:11:13
   |
11 |     screen: AlternateScreen<W>,
   |             ^^^^^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `W`
   |
note: required by a bound in `termion::screen::AlternateScreen`
  --> /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/termion-1.5.6/src/lib.rs:49:31
   |
49 | pub struct AlternateScreen<W: Write> {
   |                               ^^^^^ required by this bound in `termion::screen::AlternateScreen`
help: consider restricting type parameter `W`
   |
10 | pub struct Window<W: std::io::Write> {
   |                    ++++++++++++++++

For more information about this error, try `rustc --explain E0277`.

当我通过将所有 <W> 替换为 <W: Write> 来修复该错误时,我收到另一条错误消息,指出“此处不允许关联类型”。当我通过用 <W, W: Write>s 替换所有 <W: Write>s 来修复 that (如编译器建议的那样)时,我再次收到相同的错误消息,以及 this struct takes 2 generic arguments but 1 generic argument was supplied.

我在 SO 上搜索了很长时间,但没有找到任何有用的信息。我对 Rust 还是很陌生,所以我可能错过或误解了一些答案。有人能在这里指出我正确的方向吗?我如何才能使 Window 可以将 AlternateScreen 作为其字段之一?

为了正确使用泛型类型,您需要了解泛型参数是什么for。您不一定需要使自己的类型通用。

在这种情况下,<W> 的原因是 AlternateScreen 包装了您要写入的 Write 可用的东西 — 与 [=14= 的方式相同] 已经做到了。这就是您需要的:

pub struct Window {
    stdout: termion::raw::RawTerminal<AlternateScreen<std::io::Stdout>>,
}

然后你需要相应地调整构造它的代码,AlternateScreen::from()