fun myHashcode() : Int{
return 1
}
val functionRef1: () -> Int = Any::hashCode
val functionRef2: () -> Int = ::myHashcode
why Any::hashCode is not assigned in functionRef1 with error:
Type mismatch. Required: () → Int Found: KFunction1<Any, Int>
but when i change the code like this(this is suggested by the IDE):
val functionRef1: (Any) -> Int = Any::hashCode
then everything compiles.
Where does this Any parameter come from if it is not in the signature of the hashCode method in the Any class?
of course I know what can be done like this
val functionRef1: KFunction1<Unit, Int> = Any::hashCode
but I'm more interested in signature (Any) -> Int
The correct function type signature for your
myHashCodeis, as you correctly put it,() -> Int. It follows the general construction rule of function type signatures in Kotlin, which is:When we look at your function:
It is clear that:
IntWhen we put this all together, we get the previously mentioned function type signature.
Now, let's look at
kotlin.Any#hashCode(source):Going through the signature of this function:
hashCodeis a member ofAny, the function has a receiver type ofAnyIntWhich means, according to the construction rule, the correct function type for
Any::hashCodemust beAny.() -> Int.But, as IntelliJ mentioned to you,
(Any) -> Intalso seems to be a correct signature for this function. That is because function type signatures in Kotlin are interchangeable with their desugared counterparts.The whole "receiver type" thing in Kotlin is just syntactic sugar, because on the JVM(*) there are no receiver types. Instead, extension functions on the JVM are really just functions that take one extra parameter.
And even member functions (like
kotlin.Any#hashCode) treat their instance as a parameter when used as method references. This fact comes from Java, not Kotlin:As you can see, the function type signature in Java does not discriminate between the
thisparam and any arbitrary param, and the same goes for Kotlin, with the difference that Kotlin does have a syntactic feature to declare receiver types for function signatures. But you don't have to use it.Meaning, that
Any.() -> Intand(Any) -> Intare basically the same, or specifically, these two are both valid function signature types for thehashCode()member function ofAny.(*) The subsequently described behaviour of receiver/parameter interchangeability is most likely caused by Kotlin having been originally developed as a JVM language. However, as of today, Kotlin supports more platforms than just the JVM, namely Android, JS, Native and WASM (experimental). The described behaviour applies to all targets equally.