Вопрос:

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

kotlin

31887 просмотра

7 ответа

9198 Репутация автора

Данная функция 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)
Автор: mhshams Источник Размещён: 20.04.2013 01:04

Ответы (7)


-5 плюса

417 Репутация автора

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

Автор: ajselvig Размещён: 20.04.2013 10:44

2 плюса

9198 Репутация автора

видимо это пока не поддерживается.

больше информации:

http://devnet.jetbrains.com/message/5485180#5485180

http://youtrack.jetbrains.com/issue/KT-1183

Автор: mhshams Размещён: 21.04.2013 03:29

111 плюса

41453 Репутация автора

Решение

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

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)
Автор: Jayson Minard Размещён: 28.10.2015 10:44

5 плюса

69 Репутация автора

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

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

код:

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) })
}
Автор: Rui Zhou Размещён: 28.05.2016 04:49

2 плюса

5900 Репутация автора

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

fun main(args: Array<String>) {
    runAFunc(::runLines)
}


fun runAFunc(predicate: (Int) -> (Unit)) {
   val a = "five"
   if (a == "five") predicate.invoke(5) else predicate.invoke(3)

}

fun runLines(numbers: Int) {
    var i = numbers
    while (i > 0) {
        println("printed number is $i")
        i--
    }
}
Автор: erluxman Размещён: 23.05.2017 10:48

1 плюс

2333 Репутация автора

Котлин 1.1

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

лайк

    foo(::buz) // calling buz here

    fun buz() {
        println("i am called")
    }
Автор: Connecting life with Android Размещён: 18.08.2017 11:22

0 плюса

4339 Репутация автора

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 })
Автор: CoolMind Размещён: 19.03.2019 07:52
Вопросы из категории :
32x32