I want to define a Kotlin generic function that takes a lambda as a parameter, but I want to restrict the allowed types of lambdas parameters and return types. How do I do this in Kotlin?
In the following example, I expected the constraint: where T: Base, V: (T) -> Unit
to mean that V
can only be functions whose first parameter implements Base
.
However, I see that the compiler ignores the T: Base
part of the constraint and will accept any (Any) -> Unit
.
interface Base
fun <T, V> exampleGenericFunction(func: V) where T: Base, V: (T) -> Unit {
println("func is $func")
}
class ImplementsBase : Base
class DoesNotImplementBase
fun main() {
val f1: (ImplementsBase) -> Unit = { }
exampleGenericFunction(f1)
val f2: (DoesNotImplementBase) -> Unit = { }
exampleGenericFunction(f2) // expected this to be a compilation error
}
CodePudding user response:
This unexpected behavior was caused by a bug in the Kotlin >=1.4
compiler.
This bug can be tracked here: https://youtrack.jetbrains.com/issue/KT-48935.