Intereting Posts
Android M запрашивает разрешение в onSurfaceTextureAvailable callback не в действии java.lang.ClassNotFoundException: Не нашел класс «com.my.app.example.Main» по пути: DexPathList Возвращение котлинских кодов Java в Android Studio Canary 5 каков официальный / правильный способ создания сущности и файла Dao при использовании kotlin Как вызвать функцию верхнего уровня из метода или функции расширения одной и той же сигнатуры? Модуль библиотеки Android, разработанный в Kotlin, экспортируется в приложение Java, вызывающее неудачное разрешение: Lkotlin / jvm / internal / Intrinsics RxJava2 как отделить различную реализацию наблюдаемого излучателя Отображение данных из базы данных MySQL с помощью студии Android Android Room + шаблон Kotlin Как работает пример простых чисел из документации Kotlin Coroutines? У kotlin coroutines есть асинхронный вызов с таймером? Android Kotlin: Ошибка Неразрешенная ссылка: DaggerAppComponent Привязать список объектов, используя Guice + Kotlin Как получить Kotlin KClass из строки имени класса пакета? Многострочный макет регулярного выражения

Котлин: Передача оператора в качестве параметра функции

У меня есть следующая функция в Котлине

fun evaluate(first:Int?, second:Int?) { var result = 0 if (v.equals('*')) { result = (first ?: 0) * (second ?: 0) } else if (v.equals('+')) { result = (first ?: 0) + (second ?: 0) } else if (v.equals('-')) { result = (first ?: 0) - (second ?: 0) } else if (v.equals('/')) { result = (first ?: 0) / (second ?: 0) } return result } 

Я хочу изменить его таким образом, чтобы я мог передавать в качестве третьего параметра необходимый оператор и вычислять выражение. Что-то вроде

 fun evaluate(first:Int?, second:Int?, op: () -> Unit):Int { return (first ?: 0).op(second ?: 0) } 

Как я могу передать оператор как функцию в этом случае? Я проверил один и тот же вопрос , но неясно, как вы можете это сделать с оператором.

Запись функции более высокого порядка с использованием типа функции в качестве параметра позволяет использовать как встроенные операторы, так и лямбда-выражения для операции, поэтому это будет выглядеть так:

 fun evaluate(first: Int?, second: Int?, op: (Int, Int) -> Int): Int { return op(first ?: 0, second ?: 0) } 

Что можно вызвать со встроенными операторами, такими как:

 val r1 = evaluate(value1, value2, Int::times) val r2 = evaluate(value1, value2, Int::plus) val r3 = evaluate(value1, value2, Int::minus) val r4 = evaluate(value1, value2, Int::div) 

И с пользовательскими функциями:

 val r5 = evaluate(value1, value2) { a, b -> (a * a) + b } 

Теперь вы также можете назначить операторы переменным, например v :

 val v: (Int, Int)->Int = Int::times // typing needed on left to avoid ambiguous alternatives // and then later... val r6 = evaluate(value1, value2, v) 

Обратите внимание, что функция, записанная для сигнатуры Int.(Int)->Int может быть передана в параметр, ожидающий (Int, Int)->Int потому что приемник будет передан в качестве первого параметра.

Изменить () -> Unit в Int.(Int) -> Int . Тогда весь другой код должен работать так, как вы его там написали.

На вызывающей стороне this первый int, а первый параметр – второй int: { other -> this * other }

вы можете попробовать сделать это:

 fun evaluate(first: Int?, second: Int? , v:String ): Int = v.op(first ?: 0, second ?: 0) fun String.op(first:Int,second:Int):Int = when (this) { "*" -> first * second "+" -> first + second //.... else -> throw Exception() } fun main(args: Array<String>) { println(evaluate(2,3,"*")) println(evaluate(2,3,"+")) }