如何在包含生锈特征的泛型类型上实现deref?

时间:2015-01-08 09:09:00

标签: rust

能够使用Deref从通用容器生成& TraitType而不是调用instance.as_ref()会相当方便。即:

(*my_container).do_thing();

VS

my_container.as_ref().do_thing();

为此,我尝试在容器类型上实现Deref,但是我收到了这个错误:

<anon>:9:28: 9:29 error: expected a reference to a trait [E0172]
<anon>:9 impl<T> Deref for HasTrait<T + Send> {

自:

use std::ops::Deref;

trait Foo {}

struct HasTrait<T> {
  data:Box<T>
}

impl<T> Deref for HasTrait<T + Send> {
  type Target = T;
  fn deref<'a>(&'a self) -> &'a T {
    return self.as_ref();
  }
}

struct IsFoo;
unsafe impl Send for IsFoo {}
impl Foo for IsFoo {}


fn main() {
  let is_foo = IsFoo;
  let foo:Box<Foo> = box is_foo as Box<Foo>;
  let has_foo = HasTrait { data: foo };
  let foo_ref:&Foo = *has_foo; 
}

我尝试使用?大小来增加T的界限以允许特征,但它似乎没有帮助?

这样做的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

这有效:

use std::ops::Deref;

struct HasTrait<T: ?Sized> {
    data: Box<T>
}

impl<T: ?Sized> HasTrait<T> {
    fn as_ref(&self) -> &T {
        &*self.data
    }
}

impl<T: ?Sized> Deref for HasTrait<T> {
    type Target = T;

    fn deref<'a>(&'a self) -> &'a T {  // '
        self.as_ref()
    }
}

trait Foo {}
struct IsFoo;
impl Foo for IsFoo {}

fn main() {
    let is_foo = IsFoo;
    let foo: Box<Foo> = box is_foo as Box<Foo>;
    let has_foo = HasTrait { data: foo };
    let foo_ref: &Foo = &*has_foo; 
}

基本上,你的问题与尺寸无关。这只是HasTrait<T + Send>

impl<T> Deref<T> for HasTrait<T + Send>

毫无意义。 T可以是任意类型,u64 + Send之类的内容也没有意义。因此,我担心,您将无法限制HasTrait仅包含 特征,而适用于Send的那些类型。没有语法,我很确定类型系统不支持它。