Scala промежуточный ранний инициализатор - PullRequest
2 голосов
/ 17 января 2020

Есть ли способ в scala использовать промежуточный ранний инициализатор?

Вот что я пытаюсь скомпилировать:

trait A { val valueA: Int = 0 }
trait B { 
  val valueB: Int 
  println(valueB)
}


class C extends A with { val valueB = valueA } with B

РЕДАКТИРОВАТЬ: ответить на вопрос Луиса

С помощью Scales можно организовать осветители с помощью конструкторов признаков. Я хотел бы параметризовать один подфикс и раннюю инициализацию с полем из суперфикса.

Вот еще один пример, который лучше относится к реальному самому масштабному случаю:

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

Ответы [ 2 ]

4 голосов
/ 17 января 2020

Просто переопределите его с помощью 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
1 голос
/ 17 января 2020

Вероятно, существуют альтернативные способы написания тестов без использования ранних инициализаторов (которые устарели), например, следующее может дать некоторые идеи

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