当 Hash + PartialEq 为 Supertraits 时,Trait 无法成为对象安全

stu*_*lyf 3 rust trait-objects

我对 Rust 还很陌生,所以这可能是一个简单的问题。

我正在尝试为处理程序创建一个小型注册表,该注册表应返回实现该TransferObject特征的任何结构:

pub trait TransferObject: Hash + PartialEq {}
Run Code Online (Sandbox Code Playgroud)

HashMap由于我存储在Trait中注册的处理程序,因此需要HashPartialEq作为 Supertraits:

pub struct RequestHandlerRegistry {
    handlers: HashMap<RequestMethod, HashMap<String, RequestHandler<dyn TransferObject>>>,
}
Run Code Online (Sandbox Code Playgroud)

但在结构中,我收到错误,因为使用了参数,TransferObject所以无法将其制成对象。我已经尝试过做这样的事情:PartialEqSelf

pub struct RequestHandlerRegistry {
    handlers: HashMap<RequestMethod, HashMap<String, RequestHandler<Box<dyn TransferObject>>>>,
}
Run Code Online (Sandbox Code Playgroud)

但我仍然遇到同样的错误。
有什么办法可以解决这个问题吗?
我还创建了一个Playground来轻松重现错误。

cdh*_*wie 7

这不起作用,因为PartialEq默认情况下意味着PartialEq<Self>. 当使用动态调度(dyn)时,没有足够的信息来了解什么Self是引用以及因此方法PartialEq可以接受什么类型的引用。

然而,你的问题掩盖了一个让你陷入困境的误解:

HashMap由于我存储在Trait中注册的处理程序,因此需要HashPartialEq其作为 Supertraits

这仅适用于用作的东西。对值没有这样的限制。

因此,你可以放弃超级特征HashPartialEq从此特征中删除;相反,您需要将Hash, PartialEq, 和Eq添加到 的#[derive]宏中RequestMethod,因为这就是您用作键的内容。

最后,您确实需要Box保存这些dyn TransferObject值以使它们具有已知的大小。