Как передать функцию функции и получить доступ к лямбда-значению переданной функции в другой функции в kotlin?

#kotlin

Вопрос:

У меня есть fun приложение, которое выполняет некоторую работу и обновляется progress во время выполнения работы:

 fun doSomeWork(/* args, */ progress: (Int) -> Unit) { 
    // ...
}
 

Я хочу перейти doSomeWork к другому fun , используя block аргумент:

 helper(/* args */) {
    doSomeWork(/* args */) {
        // it: progress
    }
}
 

Но я хочу получить progress обновление в helper funtion?

 fun helper(/* args, */ block: () -> Unit) {
    // ...

    block {
        /* I want progress here? */
    }

    // ...
}
 

Я могу только редактировать helper функцию, как я могу достичь того, чего хочу?

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

1. Можете ли вы также отредактировать вызывающего абонента helper ?

2. Способ, которым вы используете block in helper , неверен. block не принимает другую лямбду в качестве параметра. block не принимает никаких параметров. Что вы на самом деле имеете в виду block { ... } ?

3. У меня есть некоторые другие fun , похожие на doSomeWork чей последний параметр progress , я хочу каким-то образом передать fun helper их таким образом, чтобы я мог получить progress обновление в помощнике.

4. block { ... } вот чего я не понимаю, что там делать.

5. Тогда нет, это невозможно. helper ничего не знает о том, что внутри block . Он не может быть уверен, что там вообще есть progress что достать. И поскольку вы не можете изменить вызывающего абонента, вы не можете добавлять/удалять/изменять какие-либо параметры helper .

Ответ №1:

Измените helper , чтобы принять a ((Int) -> Unit) -> Unit , и измените переданный лямбда-код для вызова этого параметра:

 fun helper(/* args, */ block: ((Int) -> Unit) -> Unit) {
    // ...
    block { progress ->
        val x: Int = progress
        // this will be called every time doSomeWork receives progress from the callback
    }
    // ...
}

fun main() {
    helper { receiveProgress ->
        doSomeWork { progress ->
            receiveProgress(progress)
        }
    }
}
 

Ответ №2:

как насчет

 fun helper(/* args, */ progress: (Int) -> Unit) {
    // ...

    doSomeWork(/* args, */ ){ p ->
        progress(p)
        //Do something else with p
    }

    // or if you won't want to use the progress in the helper itself:
    doSomeWork(/* args, */ progress)
    // ...
}
 

или я неправильно понял ваш вопрос?

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

1. предположим, у меня есть какая-то другая функция doSomeWork2 с другими аргументами, но в последней она имеет progress аргумент, в этом случае мне нужно перейти doSomeWork к helper