Kotlin – 非法使用内联参数回调
我将我的lambda
作为parameter
function
转换为inline function
以提高性能。
我有typesMutableList Unit>
variables的lambda
list
作为类中的数据成员。 当我尝试添加lambda parameter
到list
。
Kotlin编译器说:
非法使用内联参数回调
这是代码
// Some code skipped object Odoo { val pendingAuthenticateCallbacks = mutableListOf Unit>() inline fun authenticate( login: String, password: String, database: String, quick: Boolean = false, crossinline callback: Authenticate.() -> Unit ) { // Following statement has error saying // Illegal usage of inline parameter callback. add 'noinline' modifier to parameter declaration. pendingAuthenticateCallbacks += callback // Error in above statement if (pendingAuthenticateCallbacks.size == 1) { // Retrofit2 Object boxing code skipped val call = request.authenticate(requestBody) call.enqueue(object : Callback { override fun onFailure(call: Call, t: Throwable) { (pendingAuthenticateCallbacks.size - 1 downTo 0) .map { pendingAuthenticateCallbacks.removeAt(it) } .forEach { it(Authenticate(httpError = HttpError( Int.MAX_VALUE, t.message!! ))) } } override fun onResponse(call: Call, response: Response) { (pendingAuthenticateCallbacks.size - 1 downTo 0) .map { pendingAuthenticateCallbacks.removeAt(it) } .forEach { it(Authenticate(httpError = HttpError( response.code(), response.errorBody()!!.string() ))) } } }) } } }
内联将lambda中的代码直接插入到调用站点中 ,从而消除了具有函数对象的开销。
例如,这大致在这里main
结果:
fun withLambda(lambda: () -> Unit) { lambda() } inline fun inlinedLambda(lambda: () -> Unit) { lambda() } fun main(args: Array) { withLambda { println("Hello, world") } inlinedLambda { println("Hello, world") } }
被转换为:
fun main(args: Array) { withLambda { println("Hello, world") } println("Hello, world") // <- Directly inserted! }
如果你有
pendingAuthenticateCallbacks += callback
这是不可能的,因为callback
必须是一个对象才能被添加到列表中。
您需要添加noinline
修饰符。
一个粗略的近似就是说,一个内联的lambda不能被当作一个对象来对待,因为它并不真正作为一个对象存在 。 它被直接使用,而不是被创建为一个对象。
当然,你可以创建一个包含lambda:
pendingAuthenticateCallbacks += { callback() } // Not a good idea
但是这会完全打败内联点(不要这样做!)。
但是,将参数设置为noinline
意味着您的方法现在有零个可以内联的lambda参数,所以您可能只需删除inline
修饰符,因为性能优势将会很小。
编译器应该认识到这一点:
请注意,如果内联函数没有可以引用的函数参数,也没有指定types参数,编译器将发出警告,因为内联这样的函数不太可能是有益的。
内联方法的主要原因是使用lambdaexpression式和genericstypes参数的性能 。 从Kotlin 1.1开始,还可以为没有后台字段的属性提供内联属性访问器。
简而言之,如果你没有lambda参数(或没有指定types参数,在这种情况下你必须 ),通常没有把函数标记为inline
。
- Java中的Kotlin内部类可公开显示
- 溢出菜单单击禁用Immersive模式 – Android 4.4 Kitkat
- 在Kotlin Android中,“AsyncTask类应该是静态还是可能发生泄漏”的正确方法是什么?
- JsonProperty不能在缩小时启用
- kotlin委托属性,在get()方法中,我可以如何访问值?
- 将传递lambda到Observable.subscribe in kotlin导致内存泄漏?
- Kotlin崩溃无法将提供的符号转换为Dependency类型的对象:org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension_Decorated
- 如何处理Android的改造反应Kotlin?
- 无法转换为org.jetbrains.kotlin.java.model.types.JeClassInitializerExecutableTypeMirror