How to create a generic function to execute a bloc...
# getting-started
w
How to create a generic function to execute a block of code after checking whether a lateinit property is initialized? Something like
Copy code
fun KProperty0<*>.doIfInitialized(block: () -> Unit) {
    // todo how to do this????
}
1
K 1
c
You can't. The code would be
Copy code
inline fun <T> KProperty0<T>.ifInitialized(block: (T) -> Unit) {
    if (isInitialized) {
        block(get())
    }
}
but the compiler doesn't allow calling
isInitialized
on a generic property, because the compiler doesn't allow calling
isInitialized
on a non-
lateinit
property:
Copy code
lateinit var a: String
var b: String = "foo"

println(::a.isInitialized)
println(::b.isInitialized) // compile error: This declaration can only be called on a reference to a lateinit property
Since there is no way to know statically if
KProperty0
is a
lateinit
or not, the compiler cannot allow calling it on a given instance.
If you wanted to propagate the compiler check to the caller, you could in theory write
Copy code
inline fun <T> @receiver:AccessibleLateinitPropertyLiteral KProperty0<T>.ifInitialized(block: (T) -> Unit) {
    if (isInitialized) {
        block(get())
    }
}
but you can't, because
kotlin.internal.AccessibleLateinitPropertyLiteral
is not public. However, the standard library could probably add this function if the maintainer wanted to.
a
You should create an issue with this proposal !
c
What's the use-case though? It's really not a big improvement...
Copy code
::a.ifInitialized {
    println(a)
}

if (a::isInitialized) {
    println(a)
}
Not everything needs syntax sugar
a
We have a lot of lateinit variables in the android view model. We need to destroy them once the scope is over. But since some of them are initialised conditionally, they are blowing up when we try to access the member functions of those lateinit vms. So wanted a clean nice extension function to do this check uniformly. Can you guys propose alternative solutions?
c
How is the extension function nicer than the
if
?
a
variable.ifInitialised { }
looks better to me than
if(::variable.isInitialised) {}
👍 1
c
It's not going to be
variable.ifInitialized
, as most it would be
::variable.ifInitialized