【问题标题】:Errors get thrown before evaluating the function in Scala在 Scala 中评估函数之前抛出错误
【发布时间】:2011-09-07 01:10:57
【问题描述】:

抱歉标题令人困惑,不知道如何更好地表达它。这是Overloading in Scala when type parameters are being used的后续跟进

错误代码如下:

def parser[T](identifier: String, default: T, modifier: String => T): T = {
        val l = args.filter(_.toLowerCase.startsWith(identifier.toLowerCase))
        println("l:")
        println(l.isEmpty)
        if(l.isEmpty) default
        else modifier(l(0).drop(identifier.length).trim)
    }

val installation: String = parser("-installation", {throw new Error("Installation not specified")}, identity)

这段代码在 main 函数中,所以 args 是通常的参数列表。如果我确实传入了 -installation asdf 参数,那么会发生错误在程序甚至可以进入解析器方法之前被抛出(发生这种情况是因为控制台中没有打印“l:false”,因此永远不会到达代码.) 我相信当

{throw new Error("Installation not specified")}

块被评估。我猜 Scala 评估该块是为了知道传递给该方法的值。有没有办法推迟评估,直到它实际命中解析器中的那段代码?

我尝试过使用惰性值,例如:

lazy val error = {throw new Error("Installation not specified")}

val installation: String = parser("-installation", error , identity)

但这也不起作用。

【问题讨论】:

    标签: exception scala


    【解决方案1】:

    如果您希望仅在需要时对其进行评估,则需要按名称传递 default=> T

    def parser[T](identifier: String, default : => T; modified: String => T): T = ...
    

    否则,函数的 arg 将在函数被调用时进行评估(按值调用)。当您调用解析器将其作为参数传递时,您的惰性 val 只会导致评估错误。

    另一方面,您可以在方法中使用惰性 val,当您不希望每次引用时都评估 按名称调用 参数。

    def f(x: => T) {
      lazy val y = x
      // use y
    }
    

    在您的情况下,它不是必需的,因为默认值在解析中最多调用一次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2019-07-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多