Подтвердить что ты не робот

Kotlin: как передать функцию как параметр другому?

Данная функция foo:

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}

Мы можем сделать:

foo("a message", { println("this is a message: $it") } )
//or 
foo("a message")  { println("this is a message: $it") }

Теперь скажем, что мы имеем следующую функцию:

fun buz(m: String) {
   println("another message: $m")
}

Есть ли способ передать "buz" в качестве параметра "foo"? Что-то вроде:

foo("a message", buz)
4b9b3361

Ответ 1

Используйте :: для обозначения ссылки на функцию, а затем:

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}

// my function to pass into the other
fun buz(m: String) {
    println("another message: $m")
}

// someone passing buz into foo
fun something() {
    foo("hi", ::buz)
}

Начиная с Kotlin 1.1 теперь вы можете использовать функции, которые являются членами класса ( "Связанные вызовы" ), путем префикса оператора ссылки на функцию пример:

foo("hi", OtherClass()::buz)

foo("hi", thatOtherThing::buz)

foo("hi", this::buz)

Ответ 2

О функции-член как параметр:

  • Класс Kotlin не поддерживает статическую функцию-член, поэтому функцию-член нельзя вызвать, например: Оператор:: add (5, 4)
  • Поэтому функция-член не может использоваться так же, как функция первого класса.
  • Полезный подход заключается в том, чтобы обернуть функцию с помощью лямбда. Это не изящно, но, по крайней мере, он работает.

код:

class Operator {
    fun add(a: Int, b: Int) = a + b
    fun inc(a: Int) = a + 1
}

fun calc(a: Int, b: Int, opr: (Int, Int) -> Int) = opr(a, b)
fun calc(a: Int, opr: (Int) -> Int) = opr(a)

fun main(args: Array<String>) {
    calc(1, 2, { a, b -> Operator().add(a, b) })
    calc(1, { Operator().inc(it) })
}

Ответ 4

Просто используйте "::" перед именем метода

fun foo(function: () -> (Unit)) {
   function()
}

fun bar() {
    println("Hello World")
}

foo(::bar) Вывод: Hello World

Ответ 5

Котлин 1.1

используйте :: для ссылки на метод.

лайк

    foo(::buz) // calling buz here

    fun buz() {
        println("i am called")
    }

Ответ 6

Если вы хотите передать-акцессоры методы.

private fun setData(setValue: (Int) -> Unit, getValue: () -> (Int)) {
    val oldValue = getValue()
    val newValue = oldValue * 2
    setValue(newValue)
}

Использование:

private var width: Int = 1

setData({ width = it }, { width })

Ответ 7

Ответ Джейсона Минарда хороший. Этого также можно достичь с помощью lambda.

fun foo(m: String, bar: (m: String) -> Unit) {
    bar(m)
}

val buz = { m: String ->
    println("another message: $m")
}

Который можно вызвать с помощью foo("a message", buz).

Вы также можете сделать это немного более typealias используя typealias.

typealias qux = (m: String) -> Unit

fun foo(m: String, bar: qux) {
    bar(m)
}

val buz: qux = { m ->
    println("another message: $m")
}

Ответ 8

В Kotlin в настоящее время не поддерживаются первоклассные функции. Были дебаты о том, будет ли это хорошей возможностью для добавления. Я лично думаю, что они должны.