I have written a `whenNotNull` function: ```inline...
# android
l
I have written a
whenNotNull
function:
Copy code
inline fun <T : Any, R> whenNotNull(input: T?, callback: (T) -> R): R? = input?.let(callback)

usage:

override fun onReceive(context: Context?, intent: Intent?) {
  whenNotNull(intent) {
    it.someAction()
  }
}
I have often problems with shadowed variable names, e.g. I cannot write:
Copy code
override fun onReceive(context: Context?, intent: Intent?) {
  whenNotNull(intent) { intent -> // shadowed
    intent.someAction()
  }
}
Is there some construct to recognize that
intent
is not null within the
callback
block, so I can write:
Copy code
override fun onReceive(context: Context?, intent: Intent?) {
  whenNotNull(intent) {
    intent.someAction()
  }
}
I have enabled some static analyzer tools which complain about the "it". I know I can just write
whenNotNull(intent) { _intent -> }
but I'm curious if there is some Kotlin construct which targets this case.
l
This looks like a good use case for the contracts api. I haven't studied it too much, but it should support this case.
e
for the record,
Copy code
intent?.let {
    intent.someAction()
}
is already smart-cast by contract, you don't need your own extension
but in a simple case like this, I don't see why you don't just use the equivalent
if (intent != null) {}
to smart-cast
l
in both cases
whenNotNull
is more expressive. I found this on stackoverflow and thought this would be idiomatic. Maybe I will drop it for the simple constructs. What do you think? And would contracts help me to achieve the smart-cast contrac...haven't checked it out yet?
e
1. I would say it is idiomatic Kotlin's style to use simple constructs when they are applicable. if you wanted the nullable result, the standard
?.let
will give you that, and if you don't, then just use
if
. 2. because of the null guard in
?.let
, it doesn't even need a contract to smart-cast to non-null within the lambda body, but yes contacts can be used in a custom extension
l
@ephemient I guess you mean "if you wanted the nullable non-null result..." Thanks for the insights.
e
I meant nullable, as in
Copy code
val maybe = intent?.let { ... }
because if you don't care about the result, just use a
if
without an
else