Tried to make pow
function from BigInteger class available as infix function with the same name. The problem is that now the pow
infix operator calls itself recursively.
Is it possible to make Java function callable using infix operator with same name as function?
package experiments
import java.math.BigInteger
infix fun BigInteger.pow(x: BigInteger): BigInteger {
return this.pow(x);
}
fun main(args : Array<String>) {
val a = BigInteger("2");
val b = BigInteger("3");
println(a + b)
println(a pow b)
}
Causes:
Exception in thread "main" java.lang.StackOverflowError
at kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull(Intrinsics.java:126)
at experiments.KotlinTestKt.pow(KotlinTest.kt)
at experiments.KotlinTestKt.pow(KotlinTest.kt:6)
If I were defining my own Java class (rather than using a library class), is there any way to mark the Java method as infix? Perhaps an annotation?
This is because when you're doing:
this.pow(x)
You're actually recursing your infix function. BigInteger doesn't have pow function that takes another BigInteger-- that's what you're defining here. And don't forget, infix functions can still be called with the dot operator!
What you probably meant to write was this:
infix fun BigInteger.pow(x: BigInteger): BigInteger {
// Convert x to an int
return pow(x.longValueExact().toInt())
}
fun main(args : Array<String>) {
val a = BigInteger("2")
val b = BigInteger("3")
println(a + b)
println(a pow b)
}
If you want to reuse BigInteger's pow method, we need to convert to an int. Unfortunately, this is potentially lossy and may overflow. You might want to consider writing your own pow method if this is a concern.
There is no way to mark a Java method "natively" as infix. You can only accomplish this by using a wrapper.
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