我可以定义一个特性,其实现必须是`!Send`?

时间:2018-05-23 15:22:22

标签: multithreading rust traits

我想定义一个特性,强制其实现者在任何情况下都不会被发送到线程之间或在线程之间共享。将特征标记为!Send就足够了,但Rust似乎不允许我这样做。

有可能吗?

示例(playground):

#![feature(optin_builtin_traits)]

// This is a syntax error
//trait ThreadThing : !Send {}

// This doesn't work either
trait ThreadThing { }
impl !Send for ThreadThing {}

2 个答案:

答案 0 :(得分:2)

不,你不能使!Send成为ThreadThing的条件。编译器不支持这种逻辑。

如果某人使用您的包可以创建一个隐式Send的类型,则在其实现的任何地方都不包含不安全的代码,并且使其不安全< / em>只是为它实现ThreadThing - 在这种情况下,你会使ThreadThing成为unsafe trait,以表明某处存在不安全的代码,而这些代码依赖于不能使用的不变量在类型系统中描述:不变的“Send未实现的事物ThreadThing”。

如果更可能的话,为实现Send的类型手动实现ThreadThing是不安全的 - 在这种情况下,您不需要做任何事情,因为{{3 }}。如果ThreadThing的实施者决定手动实施Send,他们承担的责任不仅是保证自己的不变量,还要保证ThreadThing

答案 1 :(得分:0)

答案是:是的,你可以在一些非常具体的条件下。是否需要这样做是另一回事。

如果您要否定的特征是:

,您可以为另一个特征定义负特质实施
  • 一个自动特质。
  • 来自目前的箱子。

以下内容将起作用(playground):

#![feature(optin_builtin_traits)]

auto trait Scary {}

trait ThreadThing { }
impl !Scary for ThreadThing {}

但如果你试图这样做,那就行不通了:

impl !Send for ThreadThing {}

或者Scary不是自动特征。

但请注意,通常不需要以这种方式标记特征!Send。具体的具体实现将由Rust编译器根据实现结构的内容标记为Send!Send