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

 


Споріднені теми