如何确保我的类型实现自动特征?

问题描述 投票:0回答:2

假设我有一个类似的结构:

struct Foo {
  foo: Box<dyn ToString>,
}

Copy
这样的自动特征不同,它是选择加入的,我无法将
#[derive(Send)
添加到我的结构中以要求编译器选择加入并确保
Send
由我的结构实现。

我有什么选择可以确保我的类型实现例如

Send

rust traits
2个回答
2
投票

您可以通过将函数的结果分配给常量项来静态断言它是

Send
,与常量
assert
s 的操作方式相同:

const fn assert_send<T: Send>() {}

const _: () = assert_send::<Foo>()
error[E0277]: `(dyn ToString + 'static)` cannot be sent between threads safely
   --> src/lib.rs:6:29
    |
6   | const _: () = assert_send::<Foo>();
    |                             ^^^ `(dyn ToString + 'static)` cannot be sent between threads safely
    |
    = help: the trait `Send` is not implemented for `(dyn ToString + 'static)`, which is required by `Foo: Send`
    = note: required for `Unique<(dyn ToString + 'static)>` to implement `Send`
note: required because it appears within the type `Box<(dyn ToString + 'static)>`
   --> /playground/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/boxed.rs:197:12

这样您就不必依赖于构建/运行的测试。


0
投票

这个问题已在 Rust 的 用户论坛 上提出。结论是没有真正的好方法来做到这一点。这是像

Send
这样的自动特征的弱点,它不像
Copy
那样可以选择加入。

一个简单的方法是使用需要自动特征的泛型,并尝试将您的类型与它一起使用:

#[cfg(test)]
mod tests {
  use crate::Foo;

  fn test_send<T: Send>() {}

  #[test]
  fn foo_must_be_send() {
    test_send::<Foo>();
  }
}
error[E0277]: `(dyn ToString + 'static)` cannot be sent between threads safely
   --> src/lib.rs:13:17
    |
13  |     test_send::<Foo>();
    |                 ^^^ `(dyn ToString + 'static)` cannot be sent between threads safely

它远非完美,但至少它会确保你的类型是发送,如果你正在做公共API。

另一种方法是使用

IsSend
特征:

impl IsSend for Foo {}
trait IsSend: Send {}
error[E0277]: `(dyn ToString + 'static)` cannot be sent between threads safely
   --> src/lib.rs:5:17
    |
5   | impl IsSend for Foo {}
    |                 ^^^ `(dyn ToString + 'static)` cannot be sent between threads safely
    |

但这会增加文档中的噪音。

© www.soinside.com 2019 - 2024. All rights reserved.