Are function references legal and can be null?


#1

Are function references legal and can be null?

For example I have something like this:

trait A {
  val method : () -> Unit ?
}

fun test(a : A) {
  if (a.method != null) {
  a.method()
  }
}


But compiler crashes with exception. It probably may mean Iam doing something illegal…

I also tried

val method : (() -> Unit )?

with the same result.

But If I remove null-check then it will compile.


#2

It is clearly a bug.

Please, don’t hesitate to file an issue in the tracker and provide the stack trace you are getting when the compiler crashes.


#3

Most likely, you are hitting the infamous KT-606 issue that can be worked around by saying

``

if (a.method != null) {
  (a.method)()
}

in your test() function.

The issue is being fixed now.


#4

First, I'd like to clarify that following notations have different semantics:

``

val method : () -> Unit ? // function without parameters returning Unit
val method : (() -> Unit )? // nullable reference to function without parameters returning Unit


If compiler doesn’t show any meaningful error message, but crashes with exception, it means that it contains a bug. Feel free to report it directly to Kotlin issue tracker. I have reported your problem: KT-1649.

Also, you have an error in your code: automatic typecasting from nullable to not-null value happens only for local variables. It can’t happen for properties, because declaring that property is “val” doesn’t guarantee that it will have the same value every time. It only means that no value can be assigned to this property. Therefore, to make your code work, you should save a.method to local variable and check it for null:

``

trait A {
  val method : (() -> Unit )?
}

fun test(a : A) {
  val method = a.method
  if (method != null) {
  method()
  }
}

Actually, compiler should complain when you try to invoke nullable function reference, it’s a known issue which is going to be fixed soon: KT-1264