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

Kotlin 如何执行val的多步骤初始化,kotlin,Kotlin,为了学习一点kotlin,我正在构建一个基于经典论文的解析器组合器库 在我的例子中,由于递归语法,我需要向前声明一个解析器。在准备最终的表达式解析器时,我需要更新转发声明 我的第一次尝试是这样的 val addLike = mulLike separatedBy addLikeSeparator val expression = forwarded.second(addLike) addLike 其思想是执行一个简短的初始化,然后返回addL

为了学习一点kotlin,我正在构建一个基于经典论文的解析器组合器库

在我的例子中,由于递归语法,我需要向前声明一个解析器。在准备最终的表达式解析器时,我需要更新转发声明

我的第一次尝试是这样的

val addLike             = mulLike separatedBy addLikeSeparator
val expression          = 
  forwarded.second(addLike)
  addLike
其思想是执行一个简短的初始化,然后返回
addLike
来初始化该值。当我做一些F#编程时,这是一种非常常见的模式,我认为这是一种很好的模式,因为它简化了隐藏初始化细节

这在kotlin中不起作用,但是:

Error:(195, 5) Kotlin: Expecting a top level declaration
这种方法也失败了:

val addLike             = mulLike separatedBy addLikeSeparator
val expression          = forwarded.second(addLike); addLike
问题似乎是
将两个
表达式
组合成一个
语句

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

val addLike             = mulLike separatedBy addLikeSeparator
val expression          = forwarded.second(addLike), addLike
在阅读了
kotlin
规范之后,我没有找到明确的解决方案,因此我转向了StackOverflow。这个模式可以在
kotlin
中以惯用的方式实现吗

更新

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

val expression          = run () {
                                forwarded.second(addLike)
                                whitespaces keepRight addLike keepLeft expectEOS()
                          }
这对我来说是可以接受的。谢谢@Eric。

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

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

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

您可以使用该函数。通过编写lambda函数,可以在其中执行初始化代码,然后将lambda的返回值指定为数据字段的值:

val expression = run()
{
    // initialization code here
    forwarded.second(addLike)

    // writing "return@run" is optional
    return@run addLike
}
您还可以使用中提到的。您可以实例化要将数据字段分配给的值,并将lambda中的初始化代码传递到:

您可以使用。这与run类似,只是lambda不会在构造过程中立即执行以初始化数据字段。相反,它将在第一次访问数据字段时执行:

val expression by lazy()
{
    // initialization code here
    forwarded.second(addLike)

    // writing "return@run" is optional
    return@lazy addLike
}
哦,还有
init
。实际上,在一个类中可以有多个
init
块,它们将按照在文件中出现的顺序执行(从上到下)


在不了解F#的情况下,您的意图有点不清楚:(您在数据/值/操作方面试图做什么?澄清一下,返回的“it”是接收者,而不是操作:)感谢您的不同建议。就我而言,我更喜欢
运行
val expression by lazy()
{
    // initialization code here
    forwarded.second(addLike)

    // writing "return@run" is optional
    return@lazy addLike
}
val addLike: SomeType
val expression: AnotherType

init {
    addLike = mulLike separatedBy addLikeSeparator
    forwarded.second(addLike)
    expression = addLike
}