Scala编译报错:trait Parsers存在意外lazy value lastNoSuccessVar问题咨询
问题根因
- 这是Scala 2.13.6及更早2.13版本的已知编译器bug,问题出在mixin编译阶段的断言校验逻辑:当trait中存在
private[this]修饰的lazy可变变量,同时业务代码里存在被闭包捕获的var变量时,编译器会误判合法结构为非法,直接触发断言失败。 - 本次报错的直接触发源是scalaxb自动生成的
xmlprotocol.scala代码:生成的Parserstrait默认会创建lastNoSuccessVar这个符合上述特征的lazy变量,刚好命中了编译器的缺陷逻辑。你业务代码ContentRulesWrapper.scala中第298行定义的isNotValid变量被闭包捕获,是本次bug触发的另一个必要条件。
解决方案
- 优先升级Scala编译器版本到2.13.7及以上,该bug已经在Scala 2.13.7版本被官方修复,是最彻底的解决方式。
- 若暂时无法升级Scala版本,可以修改业务代码中被闭包捕获的var逻辑,比如将
ContentRulesWrapper.scala中的原有逻辑:
var isNotValid: Boolean = false f._2.foreach(f => if (f == "Refer to Agreement" | f == "") isNotValid = true)
替换为不需要var的写法即可规避问题:
val isNotValid = f._2.exists(f => f == "Refer to Agreement" || f == "")
- 也可以选择升级scalaxb到最新版本,最新版scalaxb已经调整了生成代码的结构,不会再在trait中生成会触发该bug的lazy可变变量。
内容的提问来源于stack exchange,提问作者Mykhaylo Adamovych
相关产品推荐
相关产品推荐

