Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin lambda syntax confusion

I'm confused by Kotlin lambda syntax.

At first, I have

.subscribe(
          { println(it) }
          , { println(it.message) }
          , { println("completed") }
      )

which works fine.

Then I moved the onNext to another class called GroupRecyclerViewAdapter which implements Action1<ArrayList<Group>>.

.subscribe(
          view.adapter as GroupRecyclerViewAdapter
          , { println(it.message) }
          , { println("completed") }
      )

However, I got the error:

error

Error:(42, 17) Type mismatch: inferred type is () -> ??? but rx.functions.Action1<kotlin.Throwable!>! was expected
Error:(42, 27) Unresolved reference: it
Error:(43, 17) Type mismatch: inferred type is () -> kotlin.Unit but rx.functions.Action0! was expected

I can fix the error by changing to:

.subscribe(
          view.adapter as GroupRecyclerViewAdapter
          , Action1<kotlin.Throwable> { println(it.message) }
          , Action0 { println("completed") }
      )

Is there a way to write the lambda without specifying a type? (Action1<kotlin.Throwable>, Action0)

Note: subscribe is RxJava method

Edit 1

class GroupRecyclerViewAdapter(private val groups: MutableList<Group>,
                           private val listener: OnListFragmentInteractionListener?) :
RecyclerView.Adapter<GroupRecyclerViewAdapter.ViewHolder>(), Action1<ArrayList<Group>> {
like image 728
pt2121 Avatar asked Jan 23 '16 18:01

pt2121


People also ask

How do you write lambda expression in Kotlin?

A lambda expression is always surrounded by curly braces, argument declarations go inside curly braces and have optional type annotations, the code_body goes after an arrow -> sign. If the inferred return type of the lambda is not Unit, then the last expression inside the lambda body is treated as return value.

How do you pass lambda as parameter Kotlin?

In Kotlin, a function which can accept a function as parameter or can return a function is called Higher-Order function. Instead of Integer, String or Array as a parameter to function, we will pass anonymous function or lambdas. Frequently, lambdas are passed as parameter in Kotlin functions for the convenience.

How does lambda function work in Kotlin?

A lambda expression is a shorter way of describing a function. It doesn't need a name or a return statement. You can store lambda expressions in a variable and execute them as regular functions. They can also be passed as parameters to other functions or be the return value.

What is trailing lambda in Kotlin?

Passing trailing lambdas According to Kotlin convention, if the last parameter of a function is a function, then a lambda expression passed as the corresponding argument can be placed outside the parentheses: val product = items.fold(1) { acc, e -> acc * e } Such syntax is also known as trailing lambda.


2 Answers

view.adapter as GroupRecyclerViewAdapter part should be lambda func, not Action, since onError and onComplete also lambdas

so, to fix this try:

.subscribe(
          { (view.adapter as GroupRecyclerViewAdapter).call(it) }
          , { println(it.message) }
          , { println("completed") }
      )

with your names (replace Unit with your type)

class GroupRecyclerViewAdapter : Action1<Unit> {
    override fun call(t: Unit?) {
        print ("onNext")
    }
}

with lambdas

val ga = GroupRecyclerViewAdapter()
...subscribe(
    { result -> ga.call(result) },
    { error -> print ("error $error") },
    { print ("completed") })

with actions

...subscribe(
    ga,
    Action1{ error -> print ("error $error") },
    Action0{ print ("completed") })

pick one

like image 108
vigilancer Avatar answered Nov 02 '22 19:11

vigilancer


You have two versions of the subscribe method to choose from:

  • The first (the real one) has the signature subscribe(Action1<ArrayList<Group>>, Action1<Throwable>, Action0).
  • The second version is generated by the Kotlin compiler and has the signature subscribe((ArrayList<Group>>) -> Unit, (Throwable) -> Unit, () -> Unit)

In your code, however, you pass the following parameter types:

subscribe(
    view.adapter as GroupRecyclerViewAdapter, // Action1<Throwable>
    { println(it.message) },  // (Throwable) -> Unit
    { println("completed") } // () -> Unit
)

As you can see, these parameter types satisfy none of the available signatures. The other answer gives you some solutions to your problem. In addition, you can make GroupRecyclerViewAdapter implement the functional type Function1<ArrayList<Group>, Unit> (they're interfaces, too) instead of Action1<ArrayList<Group>>.

like image 43
Kirill Rakhman Avatar answered Nov 02 '22 21:11

Kirill Rakhman