#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 не реализовал это таким образом.