2014-09-15 3 views
1

У меня возникла проблема с применением шаблона торта в моем проекте. Вот ситуация в двух словах:Странное поведение при уточнении определения типа типа в Scala

У меня есть черта Workflow, которая содержит определение типа и другой признак, который можно добавить как кусок торта в конкретный рабочий процесс.

trait VeryAbstractTrait 

trait LessAbstractedTrait extends VeryAbstractTrait 

class ConcreteImpl extends LessAbstractedTrait 

class AnotherConcreteImpl extends VeryAbstractTrait 

trait Workflow { 
    type T <: VeryAbstractTrait 
} 

trait AspectToBeAddedToWorkflow { 
    self: Workflow => 

    type T <: LessAbstractedTrait 
} 

// Will compile ... 
class ConcreteWorkflow extends Workflow with AspectToBeAddedToWorkflow { 

    final type T = ConcreteImpl 

} 

// Will not compile, since AnotherConcreteImpl is not type of LessAbstractedTrait 
class AnotherConcreteWorkflow extends Workflow with AspectToBeAddedToWorklow { 

    final type T = AnotherConcreteImpl 

} 

В предыдущем примере ConcreteWorkflow компилирует и AnotherConcreteWorkflow нет - как и ожидалось - Все в порядке.

Но когда я хочу добавить бизнес-логику для моей черты AspectToBeAddedToWorkflow, которая использует тип T, компилятор говорит мне, что T-прежнему просто VeryAbstractTrait и не LessAbstractedType как я ожидал. Для того, чтобы понять, что я имею в виду, посмотрите на следующий фрагмент кода:

trait AspectToBeAddedToWorkflow { 
    self: Workflow => 

    type T <: LessAbstractedTrait 

    val t: T 

    val a: VeryAbstractTrait = t // Compiles 

    val b: LessAbstractedTrait = t 

    /* Doesn't compile: type mismatch; found : AspectToBeAddedToWorkflow.this.T required: test.TraitSelftypes.LessAbstractedTrait */ 
} 

кажется, что тип T, который определяется/очищенное признака AspectToBeAddedToWorkflow не используется в качестве типа для значения t - Даже Eclipse, подскакивает к Workflow при нажатии F3.

Может ли кто-нибудь объяснить это поведение? У кого-то есть чистое решение для этой проблемы (я знаю, что я мог бы расширить Workflow вместо использования типа self). Но это разрушает шаблон торта и имеет некоторые другие побочные эффекты, которые не очень приятны ...).

Заранее благодарен! Майкл

Edit 1:

Для того, чтобы понять, почему мне действительно нужно иметь Workflow как самостоятельный тип - В моей программе я хочу использовать поля Workflow. Как показано ниже:

trait Workflow { 
    type T <: VeryAbstractTrait 

    val field: T 

    val anotherField: String 
} 

trait AspectToBeAddedToWorkflow { 
    self: Workflow => 

    type T <: LessAbstractedTrait 

    val field: T // Now the type of field should be <: LessAbstractedTrait, but is still <: VeryAbstractTrait 

    def anything = { 
     println(anotherField) 
    } 
} 

И я не хочу, чтобы продлить AspectToBeAddedToWorkflow с Workflow, так как это может разрушить действительно хороший шаблон торт мы применили ...

+1

Возможно, http://stackoverflow.com/a/10223364/1296806 –

ответ

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