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)
Ответы
Ответ 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) })
}
Ответ 3
очевидно, это пока не поддерживается.
Дополнительная информация:
http://devnet.jetbrains.com/message/5485180#5485180
http://youtrack.jetbrains.com/issue/KT-1183
Ответ 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 в настоящее время не поддерживаются первоклассные функции. Были дебаты о том, будет ли это хорошей возможностью для добавления. Я лично думаю, что они должны.