[英]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.