【问题标题】:When should I not implement a trait for references to implementors of that trait?我什么时候不应该为引用该特征的实现者实现一个特征?
【发布时间】:2015-03-01 21:33:27
【问题描述】:

如果我有一个 trait 和一个接受泛型类型约束的函数,那么一切正常。如果我尝试传入对该类型的引用,则会出现编译错误。

trait Trait {
    fn hello(&self) -> u32;
}

struct Struct(u32);

impl Trait for Struct {
    fn hello(&self) -> u32 {
        self.0
    }
}

fn runner<T: Trait>(t: T) {
    println!("{}", t.hello())
}

fn main() {
    let s = Struct(42);

    // Works
    runner(s);

    // Doesn't work
    runner(&s);
}
error[E0277]: the trait bound `&Struct: Trait` is not satisfied
  --> src/main.rs:24:5
   |
24 |     runner(&s);
   |     ^^^^^^ the trait `Trait` is not implemented for `&Struct`
   |
   = help: the following implementations were found:
             <Struct as Trait>
note: required by `runner`
  --> src/main.rs:13:1
   |
13 | fn runner<T: Trait>(t: T) {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^

我可以通过为实现该特征的类型的任何引用实现该特征来解决此问题:

impl<'a, T> Trait for &'a T
where
    T: Trait,
{
    fn hello(&self) -> u32 {
        (*self).hello()
    }
}

我缺少的一条信息是我什么时候不应该实现这个?换一种方式问,为什么编译器不自动为我实现这个?由于它目前没有,我认为必须有这种实现是不利的情况。

【问题讨论】:

    标签: reference rust traits


    【解决方案1】:

    我什么时候不应该实现这个?换一种方式问,为什么编译器不自动为我实现这个?由于目前还没有,我认为在某些情况下使用此实现将是不利的。

    例如,Default 特征立即浮现在脑海。

    pub trait Default {
        fn default() -> Self;
    }
    

    我可以为T 实现它,但没有办法为&amp;T 自动实现它。

    【讨论】:

      【解决方案2】:

      您在此处编写的特定 trait 仅引用 self,这是可以编写您所做的附加实现的唯一原因。

      因此,将参数按值传递给runner() 可能是不可取的;相反,您应该通过参考来获取它。这条指导原则可以普遍适用:如果有可能实现该 trait 以供参考,那么而不是想知道“我应该实现它吗?”你应该想知道“我为什么实施它?”对于您将使用它的唯一情况,可能应该首先将其更改为通过引用获取对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-02
        • 2019-12-08
        • 2021-11-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多