Есть ли способ в scala использовать промежуточный ранний инициализатор?
Вот что я пытаюсь скомпилировать:
trait A { val valueA: Int = 0 }
trait B {
val valueB: Int
println(valueB)
}
class C extends A with { val valueB = valueA } with B
РЕДАКТИРОВАТЬ: ответ на вопрос Луиса
В scalatest фикстуры могут быть организованы с помощью конструкторов трейтов. Я хотел бы параметризовать одну субфикстуру и заранее инициализировать поле из суперфикстуры.
Вот еще один пример, который лучше относится к реальному масштабному случаю:
class Test extends FreeSpec {
trait CommonFixture {
val commonCaseValue: Int = 1
}
abstract trait SpecialCaseFixture {
val specialCaseValue: Int
}
"special case test #1" in new CommonCaseFixture with { val specialCaseValue = commonCaseValue } with SpecialCaseFixture {
// all fixtures fields are accessible here
}
}
Ответ 1 · рейтинг 4 · Dima
Просто переопределите его с помощью lazy val:
trait A { val valueA: Int = 100500 }
trait B {
val valueB: Int
println(valueB)
}
class C extends A with B { lazy val valueB = valueA }
new C
// prints 100500
Ответ 2 · рейтинг 1 · Mario Galic
Вероятно, существуют альтернативные способы написания тестов без использования ранних инициализаторов (которые устарели), например, следующее может дать некоторые идеи.
class FixturesSpec extends FlatSpec with Matchers {
case class FixtureA(x: Int = 42)
case class FixtureB(y: Int = -11)
trait CommonFixture {
val commonCaseValue: Int = 1
}
trait SpecialCaseFixture {
val specialCaseValue: Int
}
"traits" should "be fixtures" in new SpecialCaseFixture with CommonFixture {
override val specialCaseValue = commonCaseValue
specialCaseValue should be (1)
}
"case classes" should "be fixtures" in new FixtureA(FixtureB().y) {
x should be (-11)
}
}