我知道def
和val
以及lazy val
之间的区别,但我不确定它们对Parser Combinators的影响。我见过的所有例子都包含这样的代码:
def statement: Parser[Statement] =
ifStatement |
whileStatement |
expressionStatement | ...
通过我做过的一些实验,似乎val
和lazy val
也可以正常工作,但我不确定是否存在他们不再工作的情况,喜欢递归或定位解析器或诸如此类的东西。
请赐教!
答案 0 :(得分:2)
如果查看the api documentation,解析器构建方法和运算符是使用名称参数实现的,然后是cached using lazy val
。
话虽如此,你仍然需要注意初始化的顺序。以下代码将导致空引用异常:
val as = a.*
val a = "a"
但是以下情况很好(因为~
的参数是按名称):
val as = "a" ~ a.*
val a = "a"
将lazy
置于一切之前会“有所帮助”,但是很吵。性能不应该是一个大问题,因为通常你只想初始化一次语法。 def
表达式将针对引用的每个点初始化一次。
使用块语法,你可以有点聪明并消除“次要”制作的管道:
lazy val addExpr = {
val add = expr ~ "+" ~ expr
val sub = expr ~ "-" ~ expr
add | sub
}