1 个不稳定版本
0.1.0 | 2020 年 8 月 3 日 |
---|
#1979 在 开发工具
9KB
91 行
must-implement-trait
一个属性 proc-macro,强制类型(自动)实现指定的特质。
用法
将 must_implement_trait
属性应用于您的结构体或枚举类型
use must_implement_trait::must_implement_trait;
#[must_implement_trait(Send)]
struct Resources {
data: Rc<String>,
}
#[must_implement_trait(Send, UnwindSafe)]
enum ConfigSource {
File(String),
Database(DatabaseAdapter)
}
该属性可以接受一个或多个特质名称作为参数;它将强制实现所有这些特质。
动机
某些特质,尤其是 Send
和 Sync
,是 自动特质。这意味着它们由编译器自动实现,很少手动实现(或未实现)。它们的实现是隐式的,并且对读者来说不明显,除非查看文档。
作为库作者,您可能希望向消费者保证您的公开接口将携带这些特质。在自己的代码中,这也有助于在未实现的地方产生错误,而不是在由于特质约束违反而无法编译的消费者附近产生错误。
考虑以下示例(examples/async-future-send.rs
)
struct Resources {
data: Rc<String>,
}
struct MyResourceManager {}
#[async_trait]
impl ResourceManager for MyResourceManager {
async fn update_resources(resources: &Resources) {
// Some code to update resources...
}
}
我们在 update_resources
函数中得到了一个错误,告诉我们
error: future cannot be sent between threads safely
--> examples/async-future-send.rs:21:54
|
21 | async fn update_resources(resources: &Resources) {
| ______________________________________________________^
22 | | // Some code to update resources...
23 | | }
| |_____^ future returned by `__update_resources` is not `Send`
|
= help: within `Resources`, the trait `std::marker::Sync` is not implemented for `std::rc::Rc<std::string::String>`
默认情况下,async-trait
要求返回的 Future 是 Send
。这是一个相当自然的选择,因为 async
通常用于多线程上下文中。在这种情况下,因为我们使用了一个 Rc
而不是 Arc
,所以 Resources
不是 Send;我们在使用站点得到了一个错误。如果 Resources
在其自己的存储库中,该存储库旨在用于异步上下文中,作者可能没有意识到他们通过引入 Rc
而引入了一个破坏性变更。
根据我的经验,如果在面向异步的代码库中工作,确保大多数或所有类型都是 Send + Sync
是有意义的;如果自动实现隐式更改,很容易破坏下游代码。
通过应用 must_implement_trait
,错误被移动到类型声明
error[E0277]: `std::rc::Rc<std::string::String>` cannot be sent between threads safely
--> examples/async-future-send.rs:11:1
|
11 | #[must_implement_trait(Send)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `std::rc::Rc<std::string::String>` cannot be sent between threads safely
|
= help: within `Resources`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<std::string::String>`
= note: required because it appears within the type `Resources`
= help: see issue #48214
= note: this error originates in an attribute macro (in Nightly builds, run with -Z macro-backtrace for more info)
依赖项
~1.5MB
~35K SLoC