Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must class member function types be called with invoke?

Tags:

kotlin

fun test() {
    class Test(val foo: ((Double, Double) -> Double)?)
    val test = Test(null)

    if(test.foo != null) test.foo(1.0, 2.0)
}

The code above generates the error:

Kotlin: Reference has a nullable type '((Double, Double) -> DoubleArray)?', use explicit '?.invoke()' to make a function-like call instead.

If I follow the errors advice and change the call to test.foo?.invoke(1.0, 2.0), the code compiles but IntelliJ now reports

Unnecessary safe call on a non-null receiver of type '((Double, Double) -> DoubleArray)

Following that advice, I end up with test.foo.invoke(1.0, 2.0) which I thought was interchangeable with test.foo(1.0, 2.0); why is that not the case here?

When foo is not a class member, things work as I would expect:

fun test2() {
    val foo: ((Double, Double) -> Double)? = null

    if(foo != null) foo(1.0, 2.0)
}
like image 556
hudsonb Avatar asked Jan 08 '18 19:01

hudsonb


2 Answers

There is an open issue for this: https://youtrack.jetbrains.com/issue/KT-4113

Currently, it's target version is 1.3.

like image 137
hudsonb Avatar answered Oct 03 '22 13:10

hudsonb


The smart casting does not seem to be working correctly in this situation, I'd expect the same as you did. It works only with invoke():

enter image description here

My workaround would be using let instead:

test.foo?.let { foo ->
    foo(1.0, 2.0)
}
like image 39
s1m0nw1 Avatar answered Oct 03 '22 14:10

s1m0nw1