scala에서 "handwritten enumeration"초기화에서 버그를 발견했습니다. 물체가 안에있는 것은 sealed case class
과 object SomeCode
이므로 필기체입니다.스칼라 객체 초기화 버그
재미있는 것 - sealed case class
에 기본값이있는 경우 - 어두운 마술이 발생합니다. 우리가 object SomeCode
시작의 초기화 SomeCode.Fist
를 호출 할 때
import com.blabla.SomeCode
import org.scalatest.{Matchers, WordSpec}
class SomeCodeTest extends WordSpec with Matchers {
"SomeCode" should {
"work properly" in {
println(SomeCode.First.toString)
}
}
}
:
sealed case class SomeCode(
id: String,
legend: String)
object SomeCode {
object First extends SomeCode(id = "First", legend = "first legend")
object Second extends SomeCode(id = "Second", legend = "second legend")
val values = Seq(
SomeCode.First,
SomeCode.Second)
private val CACHE: Map[String, SomeCode] = {
val ids = values.map(_.id)
(ids zip values).toMap
}
def getById(id: String): Option[SomeCode] = CACHE.get(id)
}
그리고 하나의 테스트 : 예를 들어 우리처럼 보인다 "필기 열거"를 가지고있다. 따라서 val values
및 private val CACHE
에 대한 초기화도 실제로 시작됩니다. 우리는 우리의 sealed case class
에 대한 기본 값을 소개하면
sealed case class SomeCode(
id: String,
legend: String = "default legend")
...
object First extends SomeCode(id = "First")
object Second extends SomeCode(id = "Second")
지금 우리의 테스트를 실행 - 우리가 CACHE
에서 NPE있을 것이다.
SomeCode.First
-이 값은 입니다. 따라서 values.map(_.id)
은 NPE를 발생시킵니다. 테스트에서 우리는 SomeCode.Second
를 호출 할 경우 null
내가 그것을가이 sealed case class
확장하는 좋은 방법이 아닙니다 알지만, 그럼에도 불구하고 제대로 작동해야 SomeCode.Second
에있을 것입니다. 어쩌면 내가 스칼라에서 뭔가를 이해하지 못할 수도 있지만, 현재 그것은 나를 위해 컴파일러 버그처럼 보입니다.
scalaVersion := "2.11.7"
또한 나는 스칼라 - 랭에 문제를 만들 :
val values = Seq(SomeCode.First, SomeCode.Second)
: 우리가 SomeCode.First.toString
를 호출 할 때 SomeCode.First
다음 코드에 null
로 끝나는되기 때문에 문제가 일어나고 https://issues.scala-lang.org/browse/SI-9929
가 뭔가 코드 예제에 없음을 수 있을까? 왜냐하면, 주어진 코드로 당신이 묘사하는 행동을 재현 할 수 없기 때문입니다. 즉, 'Works fine for me' –
@SaschaKolberg는 기본값 인'legend : String = "default legend")로 잘 작동하고 확장 객체에이 값을 설정하지 않습니다. – invis
아니요, 그렇지 않습니다. –