简体   繁体   English

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

[英]When should I not implement a trait for references to implementors of that trait?

If I have a trait, and a function that accepts a generic type constrained to that type, everything works fine. 如果我有一个特征,并且接受一个约束到该类型的泛型类型的函数,一切正常。 If I try to pass in a reference to that type, I get a compilation error. 如果我尝试传入对该类型的引用,我会收到编译错误。

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) {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^

I can fix the issue by implementing the trait for any reference to a type that implements the trait: 我可以通过为实现特征的类型的任何引用实现特征来解决问题:

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

The piece of information that I'm missing is 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. 由于目前没有,我认为必须存在这种实施方式不利的情况。

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. 由于目前没有,我认为必须存在这种实施方式不利的情况。

As an example, the Default trait immediately came to mind. 举个例子,我们立刻想到了Default特质。

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

I could implement it for T , but there is no way to automatically implement it for &T . 我可以为T实现它,但是没有办法为&T自动实现它。

The particular trait you are writing here only takes self by reference, and that is the only reason it is possible to write the additional implementation you did. 您在此处撰写的特定特征仅通过引用self ,这是可以编写您执行的其他实现的唯一原因。

For this reason, taking the parameter to runner() by value is probably undesirable; 因此,将参数设置为runner()的值可能是不合需要的; you should instead be taking it by reference. 你应该参考它。 This guideline can apply generally: if it is possible to implement the trait for a reference then rather than wondering “should I implement it?” you should wonder “why would I implement it?” for the only cases where you would use it should probably be altered to take the object by reference in the first place. 本指南一般可以适用:如果可以实现特征参考,而不是想知道“我应该实现它吗?”你应该想知道“我为什么实现它?”因为你应该使用它的唯一情况应该是首先要改变以通过引用获取对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何为结构体的引用实现 Add trait? - How do I implement the Add trait for a reference to a struct? 如何将具体类型的迭代器特征对象转换为特征对象的迭代器特征对象? - How can I transform an iterator trait object of concrete types into an iterator trait object of trait objects? 当用作方法参数时,&Trait和impl Trait有什么区别? - What is the difference between &Trait and impl Trait when used as method arguments? 为什么引用的迭代器项不转换为特征对象引用? - Why are iterator items which are references not cast to a trait object reference? 为什么在泛型函数中对特征的引用必须实现`Sized`? - Why does a reference to a trait in a generic function have to implement `Sized`? 当使用ReadBytesExt从字节片中读取整数时,为什么会出现错误“特征边界未得到满足”? - Why do I get the error “trait bounds were not satisfied” when using ReadBytesExt to read an integer from a slice of bytes? 如何在引用而不是引用值上调用特征方法? - How do I call a trait method on a reference and not the referenced value? 何时使用引用或框包含在结构中实现特征的字段? - When to use a reference or a box to have a field that implements a trait in a struct? 我应该对引用使用 __restrict 吗? - Should I use __restrict on references? 类型特征:检查引用成员变量是否为静态 - Type trait: Check if reference member variable is static or not
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM