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:(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>> {
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.
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.
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.
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.
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
You have two versions of the subscribe
method to choose from:
subscribe(Action1<ArrayList<Group>>, Action1<Throwable>, Action0)
.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>>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With