Kotlin. Анонимные функции. Лямбда-выражения

Анонимные функции. Лямбда-выражения. функциональный тип. Примеры


Содержание


Поиск на других ресурсах:

1. Понятие анонимной функции или лямбда-выражения. Объявление анонимной функции

В языке Kotlin функции могут объявляться:

  • с заданием имени функции. Такие функции называются именованными функциями. Более подробно об особенностях использования именованных функций рассматривается здесь;
  • без указания имени функции. Функции, не содержащие имени в своем объявлении, называются анонимными функциями. Анонимные функции еще называются лямбда-выражениями.

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

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

  • использование функции в качестве аргумента при вызове другой функции;
  • возврат функции из другой функции.

Если лямбда-выражение предполагает получение перечня параметров, то общая форма его объявления следующая:

{ params -> expression }

здесь

  • params – один или несколько параметров разделенных запятыми. Также параметры могут отсутствовать;
  • expression – выражение, определяющее использование параметров params для получения результата.

Если лямбда-выражение не получает параметров, то оно имеет следующее объявление

{ -> expression }

Основное преимущество использования лямбда-выражений (анонимных функций) – компактность программного кода. Функция не объявляется лишний раз. Блок кода функции передается конкретно как аргумент. Таким образом, избегается избыточность кода.

 

2. Функциональный тип. Объявление функционального типа

Язык Kotlin допускает объявлять тип анонимных функций или лямбда выражений. Такой тип называется функциональным типом. Функциональный тип позволяет расширить возможности использования лямбда-выражений.

Функциональный тип определяет характерные особенности лямбда-выражения, а именно:

  • количество входных параметров функции;
  • типы параметров функции;
  • тип возвращаемого результата.

Если в программе определен функциональный тип, то объявляется переменная этого типа. Переменная функционального типа может передаваться в код как обычная переменная.

Общая форма объявления переменной функционального типа следующая:

val lambdaExpr = { params -> expression }

здесь

  • lambdaExpr – имя переменной, определяющей лямбда-выражение.

 

3. Примеры использования анонимных функций (лямбда-выражений)
3.1. Определить количество вхождений числа в массиве

В примере определяется количество вхождений чисел 5 и 8 в заданном массиве целых чисел.

 

fun main(args:Array<String>) {

  // 1. Создать массив целых чисел
  var AI : Array<Int> = arrayOf(2, 3, 2, 5, 5, 8, 5, 2, 3, 4, 7);

  // 2. Создать лямбда-выражение, которое получает целое число
  //    и возвращает true, если это число равно 5. Иначе лямбда-выражение
  //   возвращает false
  val isNumber = { num:Int -> num == 5 }

  // 3. Вычислить количество чисел 5, передать в функцию count()
  //    лямбда-выражение
  val n5 = AI.count(isNumber) // n = 3
  println("n5 = " + n5)

  // 4. Вычислить количество чисел 8, лямбда-выражение передается
  //   непосредственно без создания ссылки на него
  val n8 = AI.count({ num:Int -> num==8 })
  println("n8 = " + n8)
}

Результат выполнения программы

n5 = 3
n8 = 1

 

3.2. Лямбда-выражение, возвращающее число 50

 

fun main(args:Array<String>) {
  // Лямбда-выражение, которое возвращает число 50
  val num50 = { -> 50 }

  // Вызов лямбда-выражения
  var x = num50()

  // Вывод результата
  println("x = " + x)
}

Результат выполнения программы

x = 50

 

3.3. Определить количество вхождений заданного символа в строке

В примере определяется количество вхождений символов ‘o’ и ‘l’ в строке s.

fun main(args:Array<String>) {

  // 1. Задана некоторая строка
  var s : String
  s = "Hello, world!"

  // 2. Объявить лямбда-выражение, которое возвращает true,
  //   если символ равен букве 'o'
  val isCharacter = { c : Char -> c == 'o'}

  // 3. Использовать лямбда-выражение isCharacter, для
  //   подсчета количества символов 'o' в строке s
  var count = s.count(isCharacter)
  println("count = " + count);

  // 4. Использовать встроенное лямбда-выражение для
  //   определения количества символов 'l' в строке s
  count = s.count({c:Char -> c == 'l'})
  println("count = " + count)
}

 

3.4. Лямбда-выражение, вычисляющее сумму двух чисел

 

fun main(args:Array<String>) {
  // Сумма двух чисел
  val sum={ a:Double, b:Double -> a*b }

  // Вызов лямбда-выражения
  println("sum = " + sum(5.0,8.0))
}

Результат выполнения программы

sum = 40.0

 

3.5. Определить, есть ли в заданном массиве хотя бы один элемент больше 5. Функция any()

Использование функции any() в сочетании с лямбда-выражением позволяет определить, соответствует ли хотя бы один элемент массива заданному условию.

 

fun main(args:Array<String>) {
  // Задан некоторый массив
  var A : Array<Int> = arrayOf(2, 3, 7, 10, -4, -11)

  // Есть ли в массиве хотя бы один элемент больше 5
  val ItemMoreThan5 = { item : Int -> item>5 }

  // Функция any()
  var n = A.any(ItemMoreThan5)
  println("(>5) = " + n) // true
}

Результат выполнения программы

(>5) = true

 

3.6. Определить, все ли элементы в массиве не нулевые. Функция all()

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

 

fun main(args:Array<String>) {
  // Задан некоторый массив
  var A : Array<Int> = arrayOf(2, 3, 7, 10, -4, -11)
  var n : Boolean

  // Определить, все ли элементы в массиве не нулевые
  val IsNonZero = { item : Int -> item != 0}
  n = A.all(IsNonZero) // true
  println("(!=0) = " + n)
}

Результат выполнения программы

(!=0) = true

 

3.7. Получить новый массив, в котором все элементы больше 5. Функция filter()

В примере на основе массива A целых чисел формируется новый список, в котором все элементы больше числа 5.

fun main(args:Array<String>) {
  // Исходный массив
  var A : Array<Int> = arrayOf(2, 3, 7, 10, -4, -11)

  // Получить новый список, в котором все элементы больше 5,
  // функция filter()
  var B: List<Int> = A.filter({ item:Int -> item > 5}) // B = [ 7, 10 ]

  println("B = " + B)
}

Результат выполнения программы

B = [7, 10]

 

3.8. Вычислить сумму квадратов элементов массива. Функция sum()

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

 

fun main(args:Array<String>) {
  // Исходный массив
  var A : Array<Int> = arrayOf(2, 3, 7, 10, -4, -11)

  // Вычислить сумму квадратов элементов массива A
  var s = A.sumBy { item : Int -> (item*item) } // s = 299
  println("s = " + s)
}

Результат выполнения программы

s = 299

 

3.9. Вычислить сумму элементов массива, которые меньше заданного значения. Сочетание функций filter() и sum()

 

fun main(args:Array<String>) {
  // Исходный массив
  var A : Array<Int> = arrayOf(2, 3, 7, 10, -4, -11)
  var s : Int

  // Сумма элементов массива, которые меньше 0
  s = A.filter( { item : Int -> item < 0}).sum()
  println("summ (<0) = " + s)
}

Результат выполнения программы

summ (<0) = -15

 


Связанные темы