rust对T和&T实现trait意义

发布时间 2023-03-29 11:16:43作者: BabyMelvin

如果T实现了某个trait,那么整个T类型的&T,也实现了该trait了吗?不是这样的。
为什么这样,例子说明下:

trait Speaker {
    fn speak(&self);
}

struct BasicSpeaker;
impl Speaker for BasicSpeaker {
    fn speak(&self) {
        println!("Hello!");
    }
}

let speaker = BasicSpeaker;
speaker.speak();

结果可以正确运行,结果打印"Hello!"

如果实现对BasicSpeaker的引用,仍然调用speak,Rust的点号操作会自动解引用变量,所以代码仍然可以工作。

// 为了具体说明,具体给出类型
let speaker_ref: &BasicSpeaker = &speaker;
speaker_ref.speak();

这里不要认为rust会将T自动实现&T的trait。可以用函数参数方式传递,不会发生自动解引用时候。

fn speak_to(s: impl Speaker) {
    s.speak();
}

fn main() {
    // Create a BasicSpeaker struct:
    let speaker = BasicSpeaker;
    // Pass speaker to the new function:
    speak_to(speaker);
}

直接调用没有问题,但是如果实现引用,就会出现问题:

let speaker_ref: &BasicSpeaker = &speaker;
speak_to(speaker_ref);

// 编译报错
error[E0277]: the trait bound `&BasicSpeaker: Speaker` is not satisfied
  --> src/main.rs:31:14
   |
31 |     speak_to(speaker_ref);
   |     -------- ^^^^^^^^^^^ the trait `Speaker` is not implemented for `&BasicSpeaker`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the trait `Speaker` is implemented for `BasicSpeaker`
note: required by a bound in `speak_to`
  --> src/main.rs:16:21
   |
16 | fn speak_to(s: impl Speaker) {
   |                     ^^^^^^^ required by this bound in `speak_to`

For more information about this error, try `rustc --explain E0277`.
  • 错误信息提示需要实现对&BasicSpeaker的trait Speaker才行。