将方法从特征实现移动到特征定义时,不匹配的类型错误

时间:2016-02-19 14:42:48

标签: rust

我有两个结构,<iframe class="ssrs-frame" type="text/html" ng-src="{{trustSrc(SSRS.url)}}" frameborder="0"> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8"> <meta name="viewport" content="width=device-width,initial-scale=1"> </head> <body> </body> </html> VM。我需要一个新的结构Word,其行为与Control类似,但还有一个字段VM。因为Rust没有继承,所以我尝试通过组合扩展struct。我将master的功能移到新的特征VM中,并为Core实施Core。结果代码有效。

Control

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

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 }
}

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

如果您在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
  }
}

execute位于impl Core<Control> for Control时,impl表示SelfT都是= Control,因此execute有效。但是如果T可以像特征的定义那样,Rust就不能让你的代码编译。

如何解决这个问题取决于你需要做什么。

如果你的特征总是以这种方式实现(impl Core<Something> for Somethingimpl Core<SomethingElse> for SomethingElse,但绝不是impl Core<Something> for SomethingElse),你可以从特征定义中删除参数,并且只有:< / p>

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
}