无法使用对实现特征的类型的引用来调用函数

Unable to call a function with a reference to a type implementing a trait

我在理解如何使用 Traits 和所有权方面遇到了一些困难。以下示例有效:

struct X([u8; 4]);

impl X {
   pub fn get(&self, n: usize) -> u8 {
       self.0[n]
   }
}

fn f1(x: &X) {
    println!("{}", x.get(1));
    f2(&x);
}

fn f2(x: &X) {
    println!("{}", x.get(2));    
}

fn main() {
    let z1 = X([1u8, 2u8, 3u8, 4u8]);
    f1(&z1);
}

但是当我尝试使用 get 创建特征(此处 XT)时:

trait XT {
  fn get(&self, n: usize) -> u8;
}

struct X([u8; 4]);

impl XT for X {
   fn get(&self, n: usize) -> u8 {
       self.0[n]
   }
}

fn f1<T: XT>(x: &T) {
    println!("{}", x.get(1));
    f2(&x);
}

fn f2<T: XT>(x: &T) {
    println!("{}", x.get(2));    
}

fn main() {
    let z1 = X([1u8, 2u8, 3u8, 4u8]);
    f1(&z1);
}

编译失败,出现以下错误消息:

the trait XT is not implemented for the type &T

如果我将 f2(&x) 更改为 f2(x),它会起作用。我的期望是用特征替换类型,一切都会起作用。

问题是您正试图将 &&T 传递给 f2。这意味着它期望 &T 实现 XT,那是 而不是 你所说的:你说 T 实现 XT

您可以使用 where T: XT, for<'a> &'a T: XT 子句修改 f1 以正确表达此约束,但是您不能从 main 调用 f1 因为 &X 没有实现 XT。所以你去为 that as well 添加一个实现,然后 then 代码工作......但老实说,删除那个 & 并改为调用 f2(x)

换句话说:仅仅因为一个类型实现了一个特征并不意味着指向该类型的指针实现了该特征。