Dic*_*ici 5 scala nullpointerexception
我在下面的Scala程序中发现了一种奇怪的东西(很抱歉包含所有代码,但你会明白我为什么要添加它):
object md2html extends App {
private val DEFAULT_THEME = Themes.AMAZON_LIGHT
private val VALID_OPTIONS = Set("editorTheme", "logo", "style")
try {
// some code 1
} catch {
case t: Throwable => t.printStackTrace(); exitWithError(t.getMessage)
}
// some code 2 (method definitions only)
private def parseOption(key: String, value: String) = {
println(key + " " + VALID_OPTIONS)
if (! Set("theme","editorTheme", "logo", "style").contains(key)) exitWithError(s"$key is not a valid option")
if (key == "theme") Themes(value).toMap else Map(key.drop(2) -> value)
}
// some code 3 (method definitions only)
}
Run Code Online (Sandbox Code Playgroud)
如果VALID_OPTIONS在其中一个之后定义some code...,则将其评估为null parseOption.我认为没有充分的理由.为了清晰起见,我截断了代码,但如果需要更多代码,我将很乐意添加它.
编辑:我看了一下,这是我发现的.
扩展时App,val不使用此代码初始化
object Test extends App {
printTest()
def printTest = println(test)
val test = "test"
}
Run Code Online (Sandbox Code Playgroud)
使用常规main方法,它工作正常:
object Test {
def main(args: Array[String]): Unit = {
printTest
}
def printTest = println(test)
val test = "test"
}
Run Code Online (Sandbox Code Playgroud)
0__*_*0__ 11
我曾监督你使用过extends App.不幸的是,这是Scala的另一个陷阱:
object Foo extends App {
val bar = "bar"
}
Foo.bar // null!
Foo.main(Array())
Foo.bar // now initialized
Run Code Online (Sandbox Code Playgroud)
该App特征将对象的初始化推迟到main方法的调用,因此所有的vals都在调用方法null之前main.
总之,这种App特质并val不能很好地融合.我多次陷入陷阱.如果您使用App,请避免使用vals,如果必须使用全局状态,请使用lazy vals代替.