У меня возникла проблема с применением шаблона торта в моем проекте. Вот ситуация в двух словах:Странное поведение при уточнении определения типа типа в 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
, так как это может разрушить действительно хороший шаблон торт мы применили ...
Возможно, http://stackoverflow.com/a/10223364/1296806 –