36

What would be the equivalent of that code in kotlin, nothing seems to work of what I try:

public interface AnInterface {
    void doSmth(MyClass inst, int num);
}

init:

AnInterface impl = (inst, num) -> {
    //...
}
1

5 Answers 5

41

If AnInterface is Java, it can work with SAM conversion:

val impl = AnInterface { inst, num -> 
     //...
}

Otherwise, if the interface is Kotlin:

  • Since Kotlin 1.4, it's possible to write functional interfaces :

    fun interface AnInterface {
         fun doSmth(inst: MyClass, num: Int)
    }
    val impl = AnInterface { inst, num -> ... }
    
  • Otherwise, if the interface is not functional

    interface AnInterface {
         fun doSmth(inst: MyClass, num: Int)
    }
    

    you can use the object syntax for implementing it anonymously:

    val impl = object : AnInterface {
        override fun doSmth(inst:, num: Int) {
            //...
        }
    }
    
Sign up to request clarification or add additional context in comments.

3 Comments

Why Kotlin interfaces doesn't have a similar SAM conversion to that of Java? Any way can this AnInterface { inst, num -> } apply to Kotlin interface as well?
What if I wanted to pass it to a function that takes AnInterface as a parameter. Do I write this? myFun(object : AnInterface { override fun doSmth(ints:, num: Int) { ... } }) There has to be a better way!
22

If you're rewriting both the interface and its implementations to Kotlin, then you should just delete the interface and use a functional type:

val impl: (MyClass, Int) -> Unit = { inst, num -> ... }

3 Comments

This is the true answer... the other 2 does not address the lambda implementation. However if I still want to use my own declared interface (for readability reason), does it mean I cannot use lambda?
@SiraLam you can declare a default variable name for a functional type: val listener: (name: Class, other: OtherClass) -> Unit
@SiraLam If you want the interface for readability reasons then you're probably suffering from Primitive Obsession. tl;dr - don't use primitives as arguments. What does a function with this signature do? (String) -> String Without a name, you can't reason about it. Now, what does a function with this signature do? (UserId) -> PhoneNumber - Well, the only reasonable implementation would be something that looks up user data by ID, then pulls out the phone number and returns it. If your functions don't take primitives then you don't usually need to wrap them in an interface for readability.
5

You can use an object expression

So it would look something like this:

val impl = object : AnInterface {
    override fun(doSmth: Any, num: Int) {
        TODO()
    }
}

Comments

1

To anyone who is reading this in 2022, Kotlin now has Functional (SAM) Interfaces. Please see https://kotlinlang.org/docs/fun-interfaces.html

Maybe it will save others some time depending on your use case.

1 Comment

Thank you, this should be the selected answer
1

you can also do something like this, using @lambda label


interface AnInterface {
     fun doSmth(inst: MyClass, num: Int)
}

val impl = AnInterface lambda@{inst, num ->
    //..
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.