Huy-Anh Hoang
Huy-Anh Hoang

Reputation: 797

SAM Conversion with Generics

I have my interfaced defined like so:

interface OnItemClickDelegate<T: Entity> {
    fun onItemClick(entity: T?)
}

Right now I have my interfaced defined anonymously in a different class:

var itemClickDelegate = object : OnItemClickDelegate<Derived> {
        override fun onItemClick(entity: Derived?) {
            doSomethingWith(entity)
        }
    }

This compiles fine, but when I switch it to:

var itemClickDelegate = OnItemClickDelegate<Derived> { entity -> doSomethingWith(entity) }

I get a compiler error saying:

Interface OnItemClickDelegate does not have constructors

How do I write my declaration in short notation?

Upvotes: 2

Views: 523

Answers (2)

Ricardo Carvalho
Ricardo Carvalho

Reputation: 96

From Kotlin 1.4 onwards, just add fun before the interface declaration and you're good to go, like so:

fun interface OnItemClickDelegate<T : Entity> {
    fun onItemClick(entity: T?)
}

https://kotlinlang.org/docs/whatsnew14.html#sam-conversions-for-kotlin-interfaces

Upvotes: 1

Teovald
Teovald

Reputation: 4389

Sadly, Kotlin does not support this syntax out of the box for kotlin interfaces, only java one (whether you use generics or not).

What you can do though is this :


interface OnItemClickDelegate<T : Entity> {
    fun onItemClick(entity: T?)

    companion object {
        inline operator fun <T : Entity> invoke(crossinline op: (entity: T?) -> Unit) =
            object : OnItemClickDelegate<T> {
                override fun onItemClick(entity: T?) = op(entity)
            }
    }
}

This way you can instantiate a listener like this :

  val delegate = OnItemClickDelegate<Entity> {
                    //todo -> insert your callback code here
            }

Upvotes: 4

Related Questions