2016-02-19 2 views
2

У меня есть две структуры, VM и Word. Мне нужна новая структура Control, которая ведет себя точно так же, как VM, но с еще одним полем master. Поскольку у Rust нет наследования, я пытаюсь расширить структуру через композицию. Я перемещаю функции 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 } 
} 

Что компилирует со следующей ошибкой:

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

Как я могу решить эту проблему?

+0

Спасибо за исправление моего плохого английского языка , –

ответ

2

если вы переместите исполнение в Core, в определении свойства нет ничего, что говорит о том, что T - это тот же тип, что и Self.

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, то осущ говорит, что Self и T оба = Control, так execute работы. Но если T может быть чем-то вроде определения определения, Rust не может позволить компилировать ваш код.

Как исправить это зависит от того, что вам нужно сделать.

Если ваша черта всегда означают быть реализовано таким образом (impl Core<Something> for Something или impl Core<SomethingElse> for SomethingElse но не как impl Core<Something> for SomethingElse), вы можете оставить параметр из определения признака и имеете всего:

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

Спасибо. Это именно то, что мне нужно. –

Смежные вопросы