如何执行val的多步骤初始化

为了学习一点kotlin我建立了一个基于经典论文Monadic Parser Combinators的解析器组合库。

在我的情况下,我需要转发declare解析器,因为递归语法。 准备最终表达式解析器时,我需要更新前向声明

我第一次尝试是这样的

 val addLike = mulLike separatedBy addLikeSeparator val expression = forwarded.second(addLike) addLike 

这个想法是执行一个短的初始化,然后返回addLike来初始化值。 这是一个非常常见的模式,当我做一些F#编程,我认为这是一个很好的模式,因为它简化了隐藏初始化细节。

然而,这在kotlinkotlin

 Error:(195, 5) Kotlin: Expecting a top level declaration 

这种方法也失败了:

 val addLike = mulLike separatedBy addLikeSeparator val expression = forwarded.second(addLike); addLike 

问题似乎是这样的; 将两个expressions组合成一个statement

所以我试了一下,希望它的行为有点像C / C ++,但没有运气:

 val addLike = mulLike separatedBy addLikeSeparator val expression = forwarded.second(addLike), addLike 

在阅读kotlin规范后,我发现没有明确的解决方案,所以我转向了StackOverflow。 这个模式是否可以在kotlin中以惯用的方式kotlin

更新

@Eric建议使用,如果run ,如果我更新我的代码,最终的解决方案有点像这样:

 val expression = run () { forwarded.second(addLike) whitespaces keepRight addLike keepLeft expectEOS() } 

这是我可以接受的。 谢谢@Eric。

在将对象分配给任何数据字段之前,有很多方法可以在对象上执行初始化代码。

您可以使用run功能。 通过run你可以编写一个lambda函数,在这里你可以执行你的初始化代码,然后把lambda的返回值作为数据字段的值:

 val expression = run() { // initialization code here forwarded.second(addLike) // writing "return@run" is optional return@run addLike } 

你也可以使用亚历山大·乌达洛夫的答案中提到的apply 。 你可以实例化你想分配数据字段的值,并将lambda中的初始化代码传入apply

 val variable = addLike.apply() { // initialization code here forwarded.second(this) // "this" refers to addLike within this lambda } 

你可以使用懒惰的代表 。 这与运行类似,只是lambda不会在构建期间立即执行以初始化数据字段。 而是在第一次访问数据字段时执行:

 val expression by lazy() { // initialization code here forwarded.second(addLike) // writing "return@run" is optional return@lazy addLike } 

您可以使用标准库中的apply函数。 它在接收器上执行一个操作,然后返回:

 val expression = addLike.apply { forwarded.second(this) }