0

I have these three helper extensions:

fun <T, K : BaseViewHolder> BaseQuickAdapter<T, K>.onItemClick(
        onItemClick: (adapter: BaseQuickAdapter<*, *>, position: Int, item: T) -> Unit
): BaseQuickAdapter<T, K> {
    setOnItemClickListener { adapter, _, position ->
        onItemClick(adapter, position, data[position])
    }
    return this
}

fun <T, K : BaseViewHolder> BaseQuickAdapter<T, K>.onItemClick(
        onItemClick: (position: Int, item: T) -> Unit
): BaseQuickAdapter<T, K> =
        onItemClick { _, position, item -> onItemClick(position, item) }

fun <T, K : BaseViewHolder> BaseQuickAdapter<T, K>.onItemClick(
        onItemClick: (item: T) -> Unit
): BaseQuickAdapter<T, K> =
        onItemClick { _, item -> onItemClick(item) }

every onItemClick function takes one argument less that the previous one

when I call:

onItemClick { item ->  
}

everything works fine as expected and the last method is called.

but when I remove the explicit item ad try to use it

onItemClick {
    it.doStuff()
}

I get this error:

Cannot choose among the following candidates without completing type inference:
public fun <T, K : BaseViewHolder> BaseQuickAdapter<T#1 (type parameter of humazed.github.com.kotlinandroidutils.simpleAdapter), KBaseViewHolder>.onItemClick(onItemClick: (adapter: BaseQuickAdapter<*, *>, position: Int, item: T#1) → Unit): BaseQuickAdapter<T#1, KBaseViewHolder> defined in humazed.github.com.kotlinandroidutils
public fun <T, K : BaseViewHolder> BaseQuickAdapter<T#1, KBaseViewHolder>.onItemClick(onItemClick: (item: T#1) → Unit): BaseQuickAdapter<T#1, KBaseViewHolder> defined in humazed.github.com.kotlinandroidutils
public fun <T, K : BaseViewHolder> BaseQuickAdapter<T#1, KBaseViewHolder>.onItemClick(onItemClick: (position: Int, item: T#1) → Unit): BaseQuickAdapter<T#1, KBaseViewHolder> defined in humazed.github.com.kotlinandroidutils

the full code on GitHub

I'm aware there are similar questions on SOF but they are not the same as mine and the answers don't apply here.

humazed
  • 74,687
  • 32
  • 99
  • 138
  • 1
    Is it because if you define `item` in the lambda you're telling the compiler that the lambda has only one parameter, so it can infer which overload you mean? If you don't specify a lambda parameter it can't do that so can't choose which overload you mean? – Yoni Gibbs Mar 13 '19 at 12:53
  • why it's different from `setOnClickListener {view-> }` and `setOnClickListener { }` both work. but in my case `onItemClick { item-> }` only work – humazed Mar 13 '19 at 15:07
  • 1
    Does `setOnClickListener` have multiple overloads like yours, each receiving a lambda, where the only difference is the signature of the lambda? (Forgive my ignorance: I don't code on Android, just server-side Kotlin.) – Yoni Gibbs Mar 13 '19 at 17:07
  • No, `setOnClickListener` doesn't have overloads, is there somewhere in the docs that mention that having multiple overloads prevent the type inference. because I guess it's reasonable to guess that when not explicitly defining the parameter the compiler will pick the overload with the single parameter especially when I don't have an overload with no parameters. – humazed Mar 13 '19 at 20:15
  • 1
    Cool, so that explains why `setOnClickListener` works and yours doesn't. As to your question about why the single-parameter overload isn't inferred: no, I've not seen anywhere in the docs that explicitly states this. Maybe if someone else does they can post a link here. As you say, I can see how it would make sense for the compiler to infer it, but can also see arguments for this being slightly unintuitive, which is maybe why JetBrains didn't implement it that way. – Yoni Gibbs Mar 14 '19 at 08:22

0 Answers0