scaventz
06/03/2021, 1:25 PMfun interface Foo : () -> Unit
fun interface Foo1 : Foo
fun interface Foo2 : Foo
fun test(foo: Foo2) {
println(foo)
}
fun main() {
val instance = object : Foo1 {
override fun invoke() {
}
}
test(instance) // is this allowed by design?
}
Maybe I'm not smart enough to understand why this is allowed, it makes me feel confused, is there any particular reason to support this behavior?raulraja
06/03/2021, 1:50 PMfun interface
values are coerced into any argument that can be desugared into the abstract method of the fun interface based on its shape. I think this kind of structural matching is their primary feature beyond the Function syntax for constructors in which you can avoid declaring an object
. This should also work:
test(Foo1 {})
or
fun test(f: () -> Unit)
Foo1, Foo2 and Foo as well as anonymous lambdas that return Unit and have no arguments are valid structurally because all of them can dispatch to the abstract method you are not implementing when extending () -> Unit
. fun Interfaces can’t hold state on their own, can’t have more than one abstract method and can’t include variance or additional type arguments in their members beyond those declared in the interface. I believe these requirements are there so structural matching against target arguments always desugar correctly in all cases by dispatching to the abstract method of a known shape.
I’m curious if there is a case or you think accepting a subtype like in this case Foo2
is dangerous or should be restricted. I can see how it can be puzzling though unless you know some of these ruleselizarov
06/03/2021, 2:07 PMinstance
is a subtype of () -> Unit
which is a function type. Function types in Kotlin are structural (they are determined by their structure, while is their parameter types and return type), just like a lambda {…}
in Kotlin (which is also structural). Such structural types in Kotlin are automatically converted to the named types (like Foo2
in this example), which have a matching shape (for functional types a matching shape means fun interface
with a method that has the corresponding signature).scaventz
06/03/2021, 2:26 PMscaventz
06/03/2021, 2:27 PM