Невозможно выбрать одного из следующих кандидатов, не завершив вывод типа

#kotlin #kotlin-extension

#kotlin #kotlin-расширение

Вопрос:

У меня есть эти три вспомогательных расширения:

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

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

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

каждая onItemClick функция принимает на один аргумент меньше, чем предыдущая

когда я вызываю:

 onItemClick { item -&&t;  
}
  

все работает нормально, как и ожидалось, и вызывается последний метод.

но когда я удаляю явное item объявление, попробуйте использовать it

 onItemClick {
    it.doStuff()
}
  

Я получаю эту ошибку:

 Cannot choose amon& the followin& candidates without completin& type inference:
public fun <T, K : BaseViewHolder&&t; BaseQuickAdapter<T#1 (type parameter of humazed.&ithub.com.kotlinandroidutils.simpleAdapter), KBaseViewHolder&&t;.onItemClick(onItemClick: (adapter: BaseQuickAdapter<*, *&&t;, position: Int, item: T#1) → Unit): BaseQuickAdapter<T#1, KBaseViewHolder&&t; defined in humazed.&ithub.com.kotlinandroidutils
public fun <T, K : BaseViewHolder&&t; BaseQuickAdapter<T#1, KBaseViewHolder&&t;.onItemClick(onItemClick: (item: T#1) → Unit): BaseQuickAdapter<T#1, KBaseViewHolder&&t; defined in humazed.&ithub.com.kotlinandroidutils
public fun <T, K : BaseViewHolder&&t; BaseQuickAdapter<T#1, KBaseViewHolder&&t;.onItemClick(onItemClick: (position: Int, item: T#1) → Unit): BaseQuickAdapter<T#1, KBaseViewHolder&&t; defined in humazed.&ithub.com.kotlinandroidutils
  

полный код на GitHub

Я знаю, что в SOF есть похожие вопросы, но они не совпадают с моими, и ответы здесь неприменимы.

Комментарии:

1. Это потому, что, если вы определяете item в лямбда-выражении, вы сообщаете компилятору, что лямбда-выражение имеет только один параметр, поэтому он может определить, какую перегрузку вы имеете в виду? Если вы не укажете параметр lambda, он не сможет этого сделать, поэтому не может выбрать, какую перегрузку вы имеете в виду?

2. почему это отличается от setOnClickListener {view-&&t; } и setOnClickListener { } оба работают. но в моем случае onItemClick { item-&&t; } работает только

3. setOnClickListener Имеет ли он несколько перегрузок, подобных вашей, каждая из которых получает лямбда-выражение, где единственным отличием является сигнатура лямбда-выражения? (Простите мое невежество: я не пишу код на Android, только на стороне сервера Kotlin.)

4. Нет, setOnClickListener не имеет перегрузок, есть ли где-нибудь в документах упоминание о том, что множественные перегрузки препятствуют выводу типа. поскольку, я полагаю, разумно предположить, что при явном определении параметра компилятор выберет перегрузку с помощью одного параметра, особенно когда у меня нет перегрузки без параметров.

5. Круто, это объясняет, почему setOnClickListener работает, а у вас нет. Что касается вашего вопроса о том, почему не выводится перегрузка с одним параметром: нет, я нигде в документах не видел, чтобы это явно указывалось. Возможно, если кто-то другой сделает это, он сможет опубликовать ссылку здесь. Как вы сказали, я вижу, как компилятору имело бы смысл выводить это, но также вижу, что аргументы в пользу этого немного неинтуитивны, возможно, поэтому JetBrains не реализовал это таким образом.