2016-07-19 3 views
9

Я некоторые черты, которые (после удаления функций и некоторые параметра наворотов) выглядят как:Реализация Вложенные Черты характера

trait Foo { } 
trait Boo { } 
trait Bar<T: Foo> { } 
trait Baz { } 

Если U реализует Bar<T> для некоторых T реализующего FooиU реализует Boo, то один может для осуществления внедрения Baz для U. Тем не менее, я не смог написать действующий код Rust.

Несколько попыток были:

impl<T: Foo, U: Bar<T> + Boo> Baz for U { } 

который дает

error: the type parameter T is not constrained by the impl trait, self type, or predicates [E0207]

тогда

impl<U: Bar<T> + Boo> Baz for U { } 

дает

error: type name T is undefined or not in scope [E0412]

Может ли один/как это сделать (стабильный) Rust (надеюсь, без динамической отправки)?

Редактировать: Некоторые люди намекают на некоторые подобные вопросы, на которые были по существу два подхода (и я считаю их обоих непригодны для моей ситуации):

  1. Использование связанных с ними типов. Я не хочу этого делать, потому что хочу отслеживать T, например. Я хочу написать некоторые функции, у которых есть подпись, например, fn bla<T: Foo, U: Bar<T>, V: Bar<T>>(), где я хочу знать, что U и V реализовать Bar<T> для таких жеT. (Или существует способ сделать это со связанными типами?)
  2. Использование какой-либо упаковки путем помещения U и T в структуру. Я не хочу использовать это либо потому, что у меня есть несколько уровней таких «зависимостей свойств», поэтому обертывание вещей на каждом уровне сильно раздувает код.

Таким образом, обновленный вопрос: Есть ли решение этой проблемы без использования связанных типов или оболочек?

ответ

7

Вы можете сделать это делает T ассоциированный тип:

trait Foo { } 
trait Boo { } 
trait Bar { 
    type T: Foo; 
} 
trait Baz { } 

impl<U: Bar + Boo> Baz for U 
    // this where clause is not necessary (this bound is already true) 
    // where U::T: Foo 
{ } 

I don't want to do this because I want to keep track of T , e.g. I want to write some functions which have a signature like fn bla<T: Foo, U: Bar<T>, V: Bar<T>>() where I want to know that U and V implement Bar<T> for the sameT . (Or is there way of doing this with associated types?)

Да, вы можете сделать это с соответствующими типами:

fn bla<U: Bar, V: Bar<T = U::T>>() { }