我什么时候不应该为引用该特征的实现者而实现该特征?

When should I not implement a trait for references to implementors of that 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()
    }
}

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

when shouldn't I implement this? Asked another way, why doesn't the compiler automatically implement this for me? Since it currently doesn't, I assume there must be cases where having this implementation would be disadvantageous.

举个例子,Default 特质立刻浮现在脑海中。

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

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

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

因此,按值将参数设为 runner() 可能是不可取的;您应该改为参考它。该准则可以普遍适用:如果可以为参考实施该特征,而不是想知道“我应该实施它吗?”你应该想知道“为什么 我实现它?”对于您可能会使用它的唯一情况,首先应该将其更改为通过引用获取对象。