Search code examples
androidkotlinsingle-abstract-methodobject-expression

Why do I need to put parenthesis after the name of the interface when creating an instance of a SAM interface in Kotlin?


According to Kotlin's documentation on SAM Conversions, the syntax for creating instances of SAM interfaces goes like this:

val runnable = Runnable { println("This runs in a runnable") }

It can be seen that there are no parenthesis after Runnable, the name of the interface.

Nonetheless, when I try to create an instance of the OnRatingBarChangeListener interface like this:

customRatingBar.onRatingBarChangeListener = OnRatingBarChangeListener
    {ratingBar: RatingBar, rating: Float, _: Boolean -> if (rating < 0.5f) ratingBar.rating = 0.5f}

Android Studio puts a red squiggly underline below OnRatingBarChangeListener and says: "Function invocation 'OnRatingBarChangeListener(...)' expected". Effectively, after putting the parenthesis after OnRatingBarChangeListener, the error stops appearing and my app works just fine:

customRatingBar.onRatingBarChangeListener = OnRatingBarChangeListener()
    {ratingBar: RatingBar, rating: Float, _: Boolean -> if (rating < 0.5f) ratingBar.rating = 0.5f}

Anyways, I don't understand why the parenthesis are needed if Kotlin's documentation states otherwise.

Thanks a lot for your help!


Solution

  • It's because you started the braces on the next line, so it can't tell that the lambda is part of the first expression. It's interpreting the lambda as an independent expression on the next line.

    By the way, the more convenient way to use SAM conversion would allow you to skip writing the name of the interface:

    customRatingBar.setOnRatingBarChangeListener { ratingBar, rating, _ -> 
        if (rating < 0.5f) ratingBar.rating = 0.5f
    }