运维开发网

Scala无法初始化val

运维开发网 https://www.qedev.com 2020-06-18 08:06 出处:网络 作者:运维开发网整理
我在下面的 Scala程序中发现了一种奇怪的东西(很抱歉包含所有代码,但你会明白我为什么要添加它): object md2html extends App { private val DEFAULT_THEME = Themes.AMAZON_LIGHT private val VALID_OPTIONS = Set("editorTheme", "logo", "style")
我在下面的 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)
}

如果在某个代码之一之后定义了VALID_OPTIONS,则在parseOption中将其评估为null.我认为没有充分的理由.为了清晰起见,我截断了代码,但如果需要更多代码,我将很乐意添加它.

编辑:我看了一下,这是我发现的.

扩展App时,不会使用此代码初始化val

object Test extends App {
    printTest()
    def printTest = println(test)
    val test = "test"
}

使用常规main方法,它工作正常:

object Test {
    def main(args: Array[String]): Unit = {
      printTest
    }
    def printTest = println(test)
    val test = "test"
}
我监督过你使用扩展应用程序.不幸的是,这是Scala的另一个陷阱:

object Foo extends App {
  val bar = "bar"
}

Foo.bar            // null!
Foo.main(Array())
Foo.bar            // now initialized

App trait将对象的初始化推迟到main方法的调用,因此在调用main方法之前,所有val都为null.

总之,App特性和val不能很好地混合.我多次陷入陷阱.如果您使用App,请避免使用val,如果必须使用全局状态,请改用lazy vals.

0

精彩评论

暂无评论...
验证码 换一张
取 消