【问题标题】:How do you implement deref on a generic type containing a trait in rust?如何在包含 rust 特征的泛型类型上实现 deref?
【发布时间】:2015-01-08 09:09:00
【问题描述】:

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

(*my_container).do_thing();

对比

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; 
}

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

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

【问题讨论】:

    标签: rust


    【解决方案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&lt;T + Send&gt;在这里:

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

    毫无意义。 T 可以是任意类型,u64 + Send 这样的东西没有意义。因此,恐怕您将无法限制 HasTrait 包含 only 特征,并且 only 包含 Send 的那些类型。只是没有语法,而且我很确定类型系统不支持它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-02
      • 2020-12-24
      • 2020-12-11
      • 2023-01-12
      • 2022-08-15
      • 2021-08-02
      • 2022-11-23
      • 1970-01-01
      相关资源
      最近更新 更多