1
votes

Which are the rules that make an Interface capable of being used as trailing lambda argument?

I though that the only rule was for it to be having a unique function on its definition, however I got myself into the following problem:

I had this Java interface

public interface ToolbarFragmentCallBack {
    void onNavigationClick();
}

Called from a java class:

public void addToolBar(int container, String title, boolean isParent,
                       ToolbarFragment.ToolbarFragmentCallBack callback) {
      //do something
}

Which was called from both Kotlin and Java files:

Kotlin (1):

addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
            presenter.onClickNavigationToolBar()
}

Java (2):

addToolBar(R.id.toolbar_fragment, definition.getTitle(), false, () -> {
            activity.onBackPressed();
        });

However, I recently migrated the interface to Kotlin:

interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}

And now the **Kotlin (1) ** implementation calls don't compile, with message

Type mismatch: inferred type is () -> Unit but ToolbarFragment.ToolbarFragmentCallBack! was expected

1
Oh thank, you @jsamol, i didn't know it was only for Java interfaces. Do you want to post that as an answer so I can choose it as such?htafoya

1 Answers

5
votes

Edit:

It is now possible with Kotlin 1.4.

Note, however, that SAM conversions still won't work with standard interfaces, you have to explicitly declare your interface as a functional interface:

fun interface ToolbarFragmentCallBack {
    fun onNavigationClick()
}

addToolBar(R.id.toolbar_fragment, toolbarTitle, toolbarParent) {
    presenter.onClickNavigationToolBar()
}

Old Answer:

For now Kotlin supports SAM conversions for Java interfaces only (see docs):

Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.

However, that is about to change with the new version 1.4 (see What to Expect in Kotlin 1.4):

The community has requested us to introduce support for SAM conversions for Kotlin classes. [...] SAM conversions currently only work for Java interfaces and abstract classes. The initial idea behind this design was to use function types explicitly for such use-cases. It turned out, however, that function types and typealiases don’t cover all the use-cases, and people often had to keep an interface in Java only to get a SAM-conversion for it.