I guess it's an outright "NO", but here is my class
class KotlinReceiverFunction {
val multiplyBy = fun Int.(value: Int) = this*value
companion object {
fun printMultiplicationResult(a: Int, b: Int) = a.multiplyBy(b) // error
}
}
My question - is Receiver Function only allowed within a specific scope i.e. same as Lambdas? Or, can I get to work somehow in a companion object?
Regards
CodePudding user response:
There are no restrictions on where a function with a receiver could be used. The problem in your case is different: multiplyBy
is an instance member, so you need an instance of KotlinReceiverFunction
to use it. It would be exactly the same if this function would not use a receiver:
val multiplyBy = fun (value1: Int, value2: Int) = value1*value2
companion object {
fun printMultiplicationResult(a: Int, b: Int) = multiplyBy(a, b) // error
}
To fix the problem you need to initialize an instance of KotlinReceiverFunction
:
fun printMultiplicationResult(a: Int, b: Int) =
with(KotlinReceiverFunction()) { a.multiplyBy(b) } // works
Although, I think this is not exactly what you need.
CodePudding user response:
This has nothing to do with receivers. You are using the correct receiver. It's just that things declared outside the companion object is out of scope inside the companion object:
class KotlinReceiverFunction {
val foo = 1
companion object {
fun bar() {
println(foo) // error
}
}
}
Think of KotlinReceiverFunction
and its companion object as two disconnected things. Under the hood on the JVM, they are just two separate classes KotlinReceiverFunction
and KotlinReceiverFunction$Companion
, each with their own instance members.
In the companion object, You would need an instance of KotlinReceiverFunction
to access its foo
property. This instance acts as the receiver.
companion object {
fun bar() {
println(KotlinReceiverFunction().foo) // OK
}
}
Similarly, the multiplyBy
function needs an instance of KotlinReceiverFunction
as its receiver (dispatch receiver). But this function also needs an Int
as a receiver (extension receiver)!
This makes it a little harder to access than foo
when you are in the companion object. You would need to provide the instance of KotlinReceiverFunction
with a scope function, as in broot's answer.
If you just declare the function inside the companion object, then it will work as you expect:
class KotlinReceiverFunction {
companion object {
val multiplyBy = fun Int.(value: Int) = this*value
fun printMultiplicationResult(a: Int, b: Int) = a.multiplyBy(b)
}
}
I don't see a reason why this needs to be a val
initialised with an anonymous function. You could have just done:
private fun Int.multiplyBy(value: Int) = this * value