• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

147
Views
Is it possible to null T or 'this' at the end of generic function for Kotlin?

I have in my project a listener. It is assigned to drawerLayout. I would like to in lambda function remove it and null it at once (sequentially). Is it possible to null T or this at the end of generic function.

Here is my code:

// Usage
actionBarListener?.let {
   drawerLayout.removeDrawerListener(it) // remove listener
   actionBarListener = null // null it
}

// Usage expected
actionBarListener.releaseAndSetNull {
   drawerLayout.removeDrawerListener(it) // remove listener and null it
}

// Generic
fun <T> T?.releaseAndSetNull(block: (T?) -> Unit) = apply {
    this?.apply { block.invoke(this) }
    this = null // Error: variable expected
}
over 3 years ago · Santiago Trujillo
2 answers
Answer question

0

I can think of several reasons why this could never work.

First of, the generic function doesn't know if this is a var or val. And this functionality could only works on a var

Likewise, it can't know if it's nullable, that's also a requirment.

Furthermore, it can even be the case that it's not a variable that's calling the function.

Like say you have

fun getActionBarListener() {
    return actionBarListener
}

Then somewhere else you could do

getActionBarListener().releaseAndSetNull {
   drawerLayout.removeDrawerListener(it) // remove listener and null it
}

How do you expect that to work?

Or even anonymous objects could call this function.

over 3 years ago · Santiago Trujillo Report

0

As Ivo Beckers said, this function would only work on vars, i.e. KMutableProperty0<T>. So you could write an extension on KMutableProperty0<T?>, and use reflection to set it, if you don't mind using reflection, that is.

inline fun <T: Any> KMutableProperty0<T?>.releaseAndSetNull(block: (T?) -> Unit) {
    block(this.get())
    this.set(null)
}

// or if you don't want the block to be called if the property is null:

inline fun <T: Any> KMutableProperty0<T?>.releaseAndSetNull(block: (T) -> Unit) {
    this.get()?.run(block)
    this.set(null)
}

Then suppose you have a property:

var foo: Int? = 10

You can do:

::foo.releaseAndSetNull { println("Foo: $it") }
// or if foo belongs to someObject
someObject::foo.releaseAndSetNull { println("Foo: $it") }

Looking at the generated bytecode, the way this is implemented (which is subject to change) is that each unique property referred to by a property reference in this way causes an inner class to be generated. The inner class will then have get and set methods that do their jobs with little extra cost - as they can just set the right property directly. So really the main cost is the extra inner class that is generated.

over 3 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error