我有一些实现了Hash
和MyTrait
的结构体。我将它们用作&MyTrait
特质对象。
现在我想让&MyTrait
也实现Hash
。我尝试了一些方法:
Naively,
trait MyTrait: Hash {}
:the trait `MyTrait` cannot be made into an object
Then I tried this:
impl Hash for MyTrait { fn hash<H: Hasher>(&self, hasher: &mut H) { // ... } }
but I need to delegate to the
hash
method of the concrete type ofself
, I think.So the naive next step is to put this on
MyTrait
:fn my_hash<H: Hasher>(&self, hasher: &mut H);
which brings me right back to the first point.
I read something about using a trait object instead of generic parameter, which sounds smart, so I put this on
MyTrait
fn my_hash(&self, hasher: &mut H);
Then I need to actually implement this. Preferably not by hand for every trait:
impl<T: 'static + Hash> MyTrait for T { fn as_any(&self) -> &Any { self as &Any } fn my_hash(&self, hasher: &mut Hasher) { self.as_any().downcast_ref::<T>().unwrap().hash(hasher) } }
but then
the trait bound `std::hash::Hasher: std::marker::Sized` is not satisfied `std::hash::Hasher` does not have a constant size known at compile-time
So I'd have to downcast
Hasher
…If downcasting
Hasher
is the way, I need a generic parameterH
that can convert to anAny
Hasher
, Let's try:trait AnyHasher { fn as_any(&self) -> &Any; } impl<H: 'static + Hasher> AnyHasher for H { fn as_any(&self) -> &Any { self as &Any } }
and then to downcast
impl<T: 'static + Hash, H: 'static + Hasher> MyTrait for T { // ... fn my_hash(&self, hasher: &mut AnyHasher) { let h = hasher.as_any().downcast_ref::<H>().unwrap(); self.as_any().downcast_ref::<T>().unwrap().hash(h) } }
but alas
the type parameter `H` is not constrained by the impl trait, self type, or predicates
which I guess is true, but then I'm stuck. (Also it seems kind of ridiculous so far).
我之前询问过关于
PartialEq
for trait objects的问题,因为需要具体类型的信息,所以很难。那个问题通过向下转换已经解决了,但我没有成功地将那个解决方案应用在这里。
hash
方法,然后在第二次尝试中调用它呢? - Boiethios&Hasher
),需要一个新的方法名。但我提前更改了名称并没有意义,抱歉。 - Mark