Как конвертировать Boxв коробку - PullRequest
3 голосов
/ 02 декабря 2019

В моей программе некоторые действия выполняются во вторичном потоке и их результаты: Result<(), Box<dyn Error>> отправляются обратно в первичный поток. Для ошибок достаточно разумно иметь требование Send, поэтому фактический тип - Result<(), Box<dyn Error + Send>>. Я также добавил Sync, чтобы можно было использовать метод Box from (который реализован только для простого или Sync + Send). Но после того, как результат определен в одном потоке, я хочу отбросить это требование.

Пример:

use std::error::Error;

fn test1() -> Result<(), Box<dyn Error + Sync + Send>> {
    return Err("test1".into());
}
fn test2() -> Result<(), Box<dyn Error>> {
    test1()?;
    return Ok(());
}
fn main() {
    let test2_result = test2();
    println!("test2_result: {:#?}", test2_result);
}

В конце я фактически заканчиваю:

   Compiling playground v0.0.1 (/playground)
error[E0277]: the size for values of type `dyn std::error::Error + std::marker::Send + std::marker::Sync` cannot be known at compilation time
 --> src/main.rs:7:12
  |
7 |     test1()?;
  |            ^ doesn't have a size known at compile-time
  |
  = help: the trait `std::marker::Sized` is not implemented for `dyn std::error::Error + std::marker::Send + std::marker::Sync`
  = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
  = note: required because of the requirements on the impl of `std::error::Error` for `std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>`
  = note: required because of the requirements on the impl of `std::convert::From<std::boxed::Box<dyn std::error::Error + std::marker::Send + std::marker::Sync>>` for `std::boxed::Box<dyn std::error::Error>`
  = note: required by `std::convert::From::from`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Этокажется, что эти типы несовместимы.

Так как я могу преобразовать (например, в test2) Result<(), Box<dyn Error + Send>> в Result<(), Box<dyn Error>>?

Я знаю, что это можно сделать, создав обертку, но я не хочу добавлять следующий уровень косвенности.

1 Ответ

0 голосов
/ 03 декабря 2019

Вопрос о том, как преобразовать эти два типа, все еще остается открытым.

На данный момент я переключился на https://crates.io/crates/failure ящик для обработки ошибок, в котором тип Error заменяет Box<dyn Error + Sync + Send>, также делаялегко создавать пользовательские и строковые (даже отформатированные) ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...