如果我有一个特征,并且接受一个约束于该类型的泛型类型的函数,一切正常。如果我尝试传入对该类型的引用,则会出现编译错误。
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()
}
}
我缺少的信息是不应该我实现这一点?问另一种方式,为什么编译器不会自动为我实现这个?由于它目前没有,我认为必须存在这种实施方式不利的情况。
答案 0 :(得分:5)
什么时候不应该实现这个?问另一种方式,为什么编译器不会自动为我实现这个?由于它目前没有,我认为必须存在这种实施方式不利的情况。
作为一个例子,我立刻想到了Default
特征。
pub trait Default {
fn default() -> Self;
}
我可以为T
实现它,但无法自动为&T
实现它。
答案 1 :(得分:3)
您在此处撰写的特定特征仅通过引用获取self
,这是您可以编写其他实现的唯一原因。
因此,将参数值设为runner()
可能是不合需要的;你应该参考它。本指南通常可以适用:如果可以实现特征作为参考,而不是想知道“我应该实现它吗?”你应该想知道“为什么 我实现它?”的唯一案例你应该在哪里使用它应该被改变,以便首先通过引用获取对象。