【问题标题】:Mismatched types error when moving a method from a trait implementation to a trait definition将方法从特征实现移动到特征定义时出现类型不匹配错误
【发布时间】:2016-06-01 04:21:47
【问题描述】:

我有两个结构,VMWord。我需要一个新的结构Control,它的行为就像VM,但多了一个字段master。因为 Rust 没有继承,所以我尝试通过组合来扩展结构。我将VM 的功能移动到一个新的特征Core 中,并为Control 实现Core。生成的代码有效。

struct Word<T> {
  action: fn(target: &T)
}

struct VM {
  word: Word<VM>
}

trait Core<T> {
  fn word(&self) -> &Word<T>;
  fn hello(&self) { println!("Hello"); }
  fn execute(&self);
}

impl Core<VM> for VM {
  fn word(&self) -> &Word<VM> { &self.word }
  fn execute(&self) { (self.word().action)(self); }
}

struct Control {
  word: Word<Control>,
  master: i32,
}

impl Core<Control> for Control {
  fn word(&self) -> &Word<Control> { &self.word }
  fn execute(&self) { (self.word().action)(self); }
}

fn main() {
  let vm = VM{
    word: Word {action: Core::hello}
  };
  vm.execute();
  let control = Control{
    word: Word {action: Core::hello},
    master: 0,
  };
  vm.execute();
}

execute 的两个实现是相同的。所以我将 execute 移动到 trait Core

trait Core<T> {
  fn word(&self) -> &Word<T>;
  fn hello(&self) { println!("Hello"); }
  fn execute(&self) { (self.word().action)(self); }
}

impl Core<VM> for VM {
  fn word(&self) -> &Word<VM> { &self.word }
}

impl Core<Control> for Control {
  fn word(&self) -> &Word<Control> { &self.word }
}

编译时出现以下错误:

main.rs:14:44: 14:48 error: mismatched types:
 expected `&T`,
    found `&Self`
(expected type parameter,
    found Self) [E0308]
main.rs:14   fn execute(&self) { (self.word().action)(self); }

我该如何解决这个问题?

【问题讨论】:

  • 感谢您纠正我糟糕的英语。

标签: rust


【解决方案1】:

如果您将执行移动到Core,则特征定义中没有任何内容表明TSelf 的类型相同。

trait Core<T> {
  fn word(&self) -> &Word<T>;
  fn hello(&self) { println!("Hello"); }
  fn execute(&self) { 
      (self.word() // this is a &Word<T>
          .action) // this is a fn(T)
          (self);  // this type is Self. T is not necessarily = Self
  }
}

executeimpl Core&lt;Control&gt; for Control 中时,impl 说SelfT 都是=Control,所以execute 有效。但是如果 T 可以是 trait 定义中的任何东西,Rust 就不能让你的代码编译。

如何解决它取决于您需要做什么。

如果您的 trait 总是要以这种方式实现(impl Core&lt;Something&gt; for Somethingimpl Core&lt;SomethingElse&gt; for SomethingElse 但绝不是 impl Core&lt;Something&gt; for SomethingElse),您可以从 trait 定义中删除参数并只使用:

trait Core: Sized {
  fn word(&self) -> &Word<Self>; // now you can't parametrize what 
                                 // Word to return. It will be Self.
  fn hello(&self) { println!("Hello"); }
  fn execute(&self) { (self.word().action)(self); } // ...and this works
}

【讨论】:

  • 谢谢。这正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 2019-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多