名称上是否支持kotlin参数?

时间:2019-09-30 11:55:47

标签: kotlin

Scala具有名称参数支持,其用法如下所示,是否有可能在Kotlin中实现?

  def invoke(block: => Boolean) = block

  // usage
  var exposure = 0
  invoke(exposure == 1)

我在Kotlin中使用以下方法:

fun waitFor(condition: () -> Boolean) = condition()

// usage
var exposure = 0
waitFor { exposure == 1 }

waitFor(exposure == 1) // I want its usage to look like this, but it does not compile

waitFor是我们自定义DSL的一部分,它占用一个块,并且每次调用它时都需要对其进行评估。

1 个答案:

答案 0 :(得分:0)

Kotlin不支持按名称进行呼叫,但是您可以使用委托的属性来模拟此功能(有限制),这些属性也可以在本地使用。

首先考虑科特林的懒惰价值。 Kotlin的惰性是通过委托属性实现的。惰性值是在首次访问时进行评估的,可以用作按名称调用,以防万一您只需要评估一次。

val exposure by lazy { 0 }
waitFor(exposure == 1)

您可以实现自定义的委托属性,该属性几乎为您提供按名称进行调用的语义

fun <T> callByName(block: () -> T) = object: ReadOnlyProperty<Any?, T> {
   override fun getValue(thisRef: Any?, property: KProperty<*>) = block()
}

像这样定义的变量或属性将在每次访问时使用所提供的块来进行赋值,这是比较懒惰的。这与名称不同,因为变量在其作用域内的块求值时仍在求值,这在调用方法waitFor之前发生。

val exposure by callByName { UUID.randomUUID() }
val alwaysFalse = exposure == exposure
waitFor(exposure == 1)

这在简单情况下很有用,但在您希望按名称调用整个块的情况下则无济于事。