Search code examples
kotlinlambdafunctional-interface

How to implement a functional interface as lambda in Kotlin?


I want to implement a functional kotlin interface (interface with a single abstract method) as a kotlin lambda. How to do that?

Kotlin interface

@FunctionalInterface
interface Foo{
  fun bar(input: String): String 
}

Kotlin implementation .

fun createFoo(): Foo {
   return { input: String -> "Hello $input!" }
}

↑ doesn't compile ↑

It has to be implemented as object, which is ugly as hell.

fun createFoo() = 
     object : Foo{
            override fun bar(input: String)= "Hello $input"
     }

EDIT: corrected my sample interface from java to kotlin


Solution

  • since Kotlin v1.4

    SAM conversion will be supported with version 1.4, with a new type inference algorithm.

    See:


    before Kotlin v1.4

    It works if the companion object implements the invoke function taking a lambda.

    Kotlin interface

    interface Foo{
      fun bar(input: String): String
    
       companion object { 
          inline operator fun invoke(crossinline function: (String) -> String) =
                    object : Foo{
                        override fun bar(input: String) = function(input)
                    } 
       } 
    }
    

    Kotlin implementation

    fun createFoo()= Foo { input: String -> "Hello $input!" }
    

    Functional/SAM interfaces defined in kotlin can't be implemented as Kotlin lambdas by design, see KT-7770.

    In Kotlin an functional / SAM interface is considered as an anti-pattern, a function type should be declared instead: (String)->String. The function type can be expressed as typealias to make it look and feel like an interface: typealias Foo=(String)->String.

    Note: The typealias is not visible in Java code only in Kotlin!