代码之家  ›  专栏  ›  技术社区  ›  David

`match的手臂类型不兼容

  •  1
  • David  · 技术社区  · 2 年前

    我有一些代码需要创建和使用 quick_xml::Writer 使用任何一个 File Cursor 取决于用户输入。正确的生锈方式(非继承/非向下投射)是什么 Writer

    关于堆栈溢出的所有答案似乎都很古老,建议在带有Box的堆上进行分配,但这不再有效,而且就个人而言,它感觉无论如何都是错误的。

    相关但现已过时: How do I overcome match arms with incompatible types for structs implementing same trait?

    代码:

    use std::fs::File;
    use std::io::Cursor;
    use quick_xml::Writer;
    
    fn main() {
        let some_option = Some("some_file.txt");
    
        let writer = match &some_option {
            Some(file_name) => {
                Writer::new(File::create(file_name).unwrap())
            },
            _ => {
                Writer::new(Cursor::new(Vec::new()))
            },
        };
    }
    

    错误:

    error[E0308]: `match` arms have incompatible types
      --> src\main.rs:13:13
       |
    8  |       let writer = match &some_option {
       |  __________________-
    9  | |         Some(file_name) => {
    10 | |             Writer::new(File::create(file_name).unwrap())
       | |             --------------------------------------------- this is found to be of type `Writer<File>`
    11 | |         },
    12 | |         _ => {
    13 | |             Writer::new(Cursor::new(Vec::new()))
       | |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected struct `File`, found struct `std::io::Cursor`
    14 | |         },
    15 | |     };
       | |_____- `match` arms have incompatible types
       |
       = note: expected type `Writer<File>`
                found struct `Writer<std::io::Cursor<Vec<u8>>>`
    
    For more information about this error, try `rustc --explain E0308`.
    
    2 回复  |  直到 2 年前
        1
  •  1
  •   Ry-    2 年前

    这个 dyn Writer . 例如,对于装箱特征对象,

    let destination: Box<dyn Write> = match &some_option {
        Some(file_name) => {
            Box::new(File::create(file_name).unwrap())
        }
        None => {
            Box::new(Cursor::new(Vec::new()))
        }
    };
    
    let writer = Writer::new(destination);
    

    Write the necessary blanket implementations 对这件作品进行修改。

        2
  •  1
  •   cdhowie    2 年前

    二者都 File Cursor 使生效 std::io::Write ,所以你可以通过装箱这些内在价值观来解决这个问题,给自己一个 Writer<Box<Write>> :

    let writer: Writer<Box<dyn std::io::Write>> = Writer::new(match &some_option {
        Some(file_name) => {
            Box::new(File::create(file_name).unwrap())
        },
        _ => {
            Box::new(Cursor::new(Vec::new()))
       },
    });
    

    文件 光标 价值或者,您可以使用 either Either 相反:

    let writer = Writer::new(match &some_option {
        Some(file_name) => {
            Either::Left(File::create(file_name).unwrap())
        },
        _ => {
            Either::Right(Cursor::new(Vec::new()))
        },
    });
    

    Either implements Write when both the Left and Right variants do