`match` руки имеют несовместимые типы

У меня есть код, который нужно создать и использоватьquick_xml::Writerлибо сFileилиCursorв зависимости от ввода пользователя. Каков правильный способ Rust (без наследования / без понижения) для созданияWriterс разными структурами, но с той же чертой?

Все ответы о переполнении стека кажутся старыми и рекомендуют выделять кучу с помощью Box, но это больше не работает, и лично мне это все равно кажется неправильным.

Связано, но устарело: как мне преодолеть соответствие рук с несовместимыми типами для структур, реализующих один и тот же признак?

Код:

      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`.

1 ответ

The 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имеет необходимые общие реализации , чтобы сделать вариации этой работы.

Другие вопросы по тегам