Why do i have to use function reference to store a function into a variable:
fun someFunction(i: Int): Unit = println(i)
val funVal = someFunction // Compile error!
val funVal2 = ::someFunction // Function reference works fine
But I can store lambda in a variable directly:
val someLambda: (Int) -> Unit = { i: Int -> println(i) }
Functions stored in variables do not need function names. They are always invoked (called) using the variable name. The function above ends with a semicolon because it is a part of an executable statement.
Functions as variables. Functions in Kotlin are simply another data type. You can assign them to variables and constants just as you can any other type of value, such as an Int or a String . This function takes two parameters and returns the sum of their values.
Kotlin gives us the power to declare high-order functions. In a high-order function, we can pass and return functions as parameters.
Kotlin uses two different keywords to declare variables: val and var . Use val for a variable whose value never changes. You can't reassign a value to a variable that was declared using val . Use var for a variable whose value can change.
It is about correct syntax. Or more precisely, about the ability of the compiler to understand what you are trying to tell it!
When you look at your different examples, you can find that the accepted cases use specific chars, like the colon for example. That makes it simply easier to deduct what the code is meant to say.
So, one possible reason could be a trade off. Sure, when you have
val a = b
you could allow b to be a method reference. But what if you wanted to call b() instead?! The "lexicographic" distance between b and b() is pretty small!
So to not allow for that syntax makes it a) easier to parse code, and b) harder for you to have small typos change the meaning of your code!
Because fun someFunction(i: Int): Unit = println(i)
despite being a function
is a more concrete type called method
, that's why you need the method reference syntax. Something similar happens in Scala
too
Example
fun method(value: String) = println(value)
val function: (String) -> Unit = { value -> println(value) }
val methodRef = ::method
val functionRef = function
Further reading "Kotlin programmer dictionary"
The GhostCat's answer is quite correct, but it's missing an important point, which I think should be mentioned to make it complete.
The callable references syntax is uniform across functions and properties, but in case of properties, it is absolutely necessary to distinguish the property access foo
from its callable reference ::foo
.
val foo: Int = TODO()
val fooValue = foo
val fooReference = ::foo
So, while functions in fact could get callable reference syntax with just the function name foo
(it is not ambiguous with the function call foo()
in any way), for uniformity, functions share the callable reference syntax ::foo
with properties, which in turn needed some special syntactic form of callable references.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With