if ( Form1.InvokeRequired ) {
Form1.Invoke((Action)delegate{MessageBox.Show(Form1,"Hello");});
}
Порядок инициализации тривиальных переменных (val
) и ленивых переменных (lazy val
) различен.
val
инициализируются в порядке , они описаны в файле.
lazy val
инициализируются при первом доступе .
В вашем случае Project
содержит Task
, поэтому для projectRead
требуется инициализированный taskRead
.
В вашем коде, без lazy
, projectRead
объявляется перед taskRead
, поэтому taskRead
все еще null
, когда projectRead
это нужно. Вот почему вы получили NPE.
Тем не менее, компилятор может найти неявное taskRead
и не выдавать ошибку .
Ваше исправление с lazy
работает, потому что taskRead
теперь инициализирует при первом доступе . Теперь taskRead
инициализируется, когда projectRead
запрашивает его. NPE ушел.
Вы можете добиться того же исправления, переключив порядок объявления:
trait JsonConverter {
implicit val taskWrite: OWrites[Task] = Json.writes[Task]
implicit val taskRead: Reads[Task] = Json.reads[Task]
implicit val projectWrite: OWrites[Project] = Json.writes[Project]
implicit val projectRead: Reads[Project] = Json.reads[Project]
}