为什么RegexParsers使用" def"而不是" lazy val"?

时间:2013-10-18 13:32:44

标签: parsing scala parser-combinators

在关于RegexParsers的Scaladoc中,有以下代码:

object Calculator extends RegexParsers {
  def number: Parser[Double] = """\d+(\.\d*)?""".r ^^ { _.toDouble }
  def factor: Parser[Double] = number | "(" ~> expr <~ ")"
...

我不明白为什么我们用def而不是vallazy val写的?我会这样写:

object Calculator extends RegexParsers {
  lazy val number: Parser[Double] = """\d+(\.\d*)?""".r ^^ { _.toDouble }
  lazy val factor: Parser[Double] = number | "(" ~> expr <~ ")"
...

1 个答案:

答案 0 :(得分:1)

它有一个实际的语义原因。查看Parser的类型签名:

 abstract class Parser[+T] extends (Input) ⇒ ParseResult[T]

Parser[T]实际上是一种抽象的InputParseResult[T]的函数。在许多(可能是大多数)情况下,此函数捕获正在执行的解析状态的某些方面。如果以val(懒惰或其他方式)捕获此类产品,则不能在给定的解析树中的多个位置使用它。唯一可以制作val的作品是固定终端,例如标点符号和关键字。

<强>附录

自从我使用Scala组合器解析器以来,已经有好几年了,而且当时我还是一个Scala新手,所以完全有可能我错了。但是,我的回忆是Reader表示整个输入不是输入,而是输入的特定子序列。因此,如果制作没有固定的输入序列,则制作不能是val

我确实有一个需要解析器的小方项目,所以当我有时间时,我可以确认或反驳这种理解。