Вы можете сделать рекурсивную функцию не встроенной и взять KClass
, представляющий желаемый тип, и сделать дополнительную функцию-обертку:
fun <T : View> ViewGroup.allViewsOfTypeT(type: KClass<T>, f: (T) -> Unit) {
afterMeasured {
for (i in 0 until childCount) {
val child = getChildAt(i)
if (type.isInstance(child)) f(child)
if (child is ViewGroup) child.allViewsOfTypeT(type, f)
}
}
}
inline fun <reified T : View> ViewGroup.allViewsOfTypeT(f: (T) -> Unit)
= allViewsOfTypeT(T::class, f)
Вы не можете встроить рекурсивную функцию, если не можете развернуть ее в цикл, потому что встраивание функции означает, что после компиляции она больше не является функцией - вместо этого она копируется непосредственно в позвоните на сайт. Нет функции, нет стека вызовов, нет рекурсии. В этих случаях вы должны передать KClass
вместо того, чтобы сделать обобщенный параметр reified, что в основном и будет сделано в Java, если вам нужна проверка instanceof
с универсальным параметром.
Однако, вы можете свернуть свой стек ( Путь от рекурсии к итерации ):
inline fun <reified T : View> ViewGroup.allViewsOfTypeT(action: (T) -> Unit) {
val views = Stack<View>()
afterMeasured {
views.addAll((0 until childCount).map(this::getChildAt))
}
while (!views.isEmpty()) {
views.pop().let {
if (it is T) action(it)
if (it is ViewGroup) {
afterMeasured {
views.addAll((0 until childCount).map(this::getChildAt))
}
}
}
}
}
Я не проверял это, но общая идея должна работать.