Ошибки вызываются до оценки функции в Scala - PullRequest
0 голосов
/ 06 сентября 2011

Извиняюсь за запутанный заголовок, не знал, как это выразить лучше.Это продолжение перегрузки в Scala при использовании параметров типа

Вот неисправный код:

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)

Этот код находится в основной функции,поэтому аргументы - это обычный список аргументов.Если я передам аргумент -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)

, но этотоже не работает.

1 Ответ

4 голосов
/ 06 сентября 2011

Вам нужно передать default по имени с => T, если вы хотите, чтобы оно оценивалось только при необходимости

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

В противном случае аргумент функции оценивается при вызове функции (вызов по значению). Ваш ленивый val просто приводит к оценке ошибки, когда вы вызываете парсер, передавая его в качестве аргумента.

С другой стороны, вы можете использовать lazy val внутри метода, когда вы не хотите, чтобы аргумент по имени оценивался при каждой ссылке на него.

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

В вашем случае это не нужно, так как значение по умолчанию вызывается не более одного раза при разборе.

...