关于以下两种情况,我对编写代码的优点感到困惑:
class TestA {
private val foo: Boolean by lazy {
// Here is logic that return true or false
}
Case 1:
fun main() {
TestB({foo})
}
Case 2:
fun main() {
TestB(foo)
}
}
Case 1:
class TestB(private val isFoo: () -> Boolean ) {
fun checkFoo(): Boolean {
return isFoo.invoke()
}
}
Case 2:
class TestB(private val isFoo: Boolean ) {
fun checkFoo(): Boolean {
return isFoo
}
}
何时应该使用案例1或案例2?
顺便问一下,请让我知道invoke()方法如何工作?
答案 0 :(得分:2)
仅当您希望在另一端调用某些东西时才将lambda传递给其他类构造函数,这在用作回调时可能有意义,或者如果您需要具有一次又一次创建对象而不是被创建的函数静态的。在这种情况下,您将存储lambda供以后引用,并在需要时调用它。如果仅传递静态实例,例如代码中的foo
,则无需使用lambda。您应该始终不对构造函数使用lambda。有用或必要的场景在国际海事组织中很少见。
关于您对invoke
的问题:Kotlin具有许多“按惯例”起作用的功能,例如rangeTo
,equals
,contains
,compareTo
,索引运算符以及invoke
。了解约定here。
现在,每当一个类提供invoke
运算符时,就可以像调用它们一样调用该类的实例:
class InvokeMe(){
operator fun invoke(value: Int) = println("invoked with $value")
}
val obj = InvokeMe()
//both are compiled to the same code
obj(10)
obj.invoke(5)
由于每个lambda都被编译为Function
实现的kotlin.jvm.functions
实例(请参见invoke
),因此您可以如上所述调用lambda,即,使用{{ 1}}或lambda(args)
答案 1 :(得分:1)
.invoke()
只会调用lambda并给出结果,就像调用函数一样。
至于何时应传递lambda或实际值,这取决于情况。
就个人而言,我只建议在非常特殊的情况下使用lambda,过度使用它们会使您的代码非常混乱且难以重构。如果只希望将结果传递到函数中,则只需传递实际值即可。不要让别人打电话给.invoke()
。
但是lambda的一些很好的例子是回调或onClickListeners。
// A login network request with a lambda handling the result.
fun login( username: String, password: String, onResult: (Result) -> Unit ) {
// do some network call, and return a Result.
}
// note: if the last param is a lambda, you can simply move it outside the function call like this.
login( username, password ) { result ->
// use the result of the network request.
}
希望有帮助。