Kotlin. Іменовані аргументи функцій. Тип Nothing

Іменовані аргументи функцій. Тип Nothing. Перевантаження функцій


Зміст


Пошук на інших ресурсах:

1. Поняття про іменовані аргументи функцій

При виклику функції проста передача аргументів у неї може бути замінена використанням іншого синтаксису. Цей синтаксис підтримує так звані іменовані аргументи функцій. У цьому випадку, ім’я кожного параметру функції задається явно з використанням наступного синтаксису:

fun FuncName(param1 = value1, param2 = value2, ..., paramN = valueN)

де

  • param1, param2, paramN – імена параметрів, які використовуються при оголошенні функції;
  • value1, value2, valueN – значення аргументів, що передаються у функцію. Відповідно, параметр з іменем param1 отримує значення аргументу value1, параметр з іменем param2 отримує значення аргументу value2 і т.д.

Оскільки, при використанні іменованих аргументів, кожен параметр поіменно отримує своє значення, то допускається змінювати порядок слідування імен параметрів.

Наприклад, якщо функція оголошується так, що вона отримує 3 параметри з іменами a, b, c, які мають типи Int, Char, Double відповідно

// Функція, яка отримує 3 параметри типів Int, Char, Double
fun SomeFunction(a:Int, b:Char, c:Double) {
  // ...
}

то викликати цю функцію можна різними способами

// Функція, яка отримує 3 параметри типів Int, Char, Double
fun SomeFunction(a:Int, b:Char, c:Double) {
  println("a = " + a)
  println("b = " + b)
  println("c = " + c)
}

fun main(args:Array<String>)
{
  // Виклик функції SomeFunction() різними способами
  // 1. Звичайний виклик без використання іменованих аргументів
  SomeFunction(25, 'z', 2.85)

  // 2. Виклик з використанням іменованих параметрів
  // 2.1. Іменовані аргументу задаються в тому порядку, в якому
  //     відповідні параметри оголошені у функції
  SomeFunction(a = 25, b = '+', c = 3.88)

  // 2.2. Іменовані аргументи слідують в довільному порядку
  SomeFunction(c = 7.77, b = 'z', a = 33)
  SomeFunction(b = 'f', a = 100, c = 2.85)
}

 

2. Переваги використання іменованих аргументів функцій

Використання іменованих аргументів при виклику функції дає наступні переваги:

  • аргументи у функцію можна передавати у довільному порядку. Не потрібно запам’ятовувати порядок слідування параметрів при оголошенні функції;
  • програмний код передачі аргументів у функцію при її виклику стає більш зрозумілим. Ця перевага стає більш суттєвою, коли функція отримує велику кількість параметрів або імена змінних, що передаються, не співпадають з іменами параметрів.

До недоліків можна віднести збільшення текстового коду програми, що набирається у редакторі.

 

3. Приклад використання іменованих аргументів функції

У прикладі оголошується функція, яка за координатами трьох точок (x1; y1), (x2; y2), (x3; y3) визначає площу трикутника, утвореного з цих точок.

// Функція, яка отримує 6 параметрів
fun AreaTriangle(x1:Double, y1:Double,
                 x2:Double, y2:Double,
                 x3:Double, y3:Double) : Double {
  val a=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
  val b=Math.sqrt((x1-x3)*(x1-x3)+(y1-y3)*(y1-y3))
  val c=Math.sqrt((x2-x3)*(x2-x3)+(y2-y3)*(y2-y3))
  val p = (a+b+c)/2
  val s = Math.sqrt(p*(p-a)*(p-b)*(p-c))
  return s
}

fun main(args:Array<String>)
{
  // Виклик функції AreaTriangle() з використанням
  // іменованих аргументів
  val s = AreaTriangle(x2=5.5, y2=3.8, x1=2.9, y1=0.5, y3=7.7, x3=10.5)
  println("s = " + s)
}

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

s = 3.179999999999992

 

4. Тип Nothing. Призначення. Приклад

Функція може повертати тип Nothing. Це означає, що функція нічого не повертає так само як у випадку використання типу Unit. Більш детально про тип Unit описується тут.

Повернення функцією типу Nothing (на відміну від повернення типу Unit) дає наступну інформацію компілятору:

  • функція однозначно не виконається успішно. Це означає, що функція згенерує виключення або взагалі не поверне управління викликаючому коду.

Така необхідність виникає у випадках:

  • коли розробник функції відкладує реалізацію функції на потім, оскільки ще не реалізовані інші функції чи засоби, які ця функція використовує;
  • коли потрібно після виклику Nothing-функції вказати рядки, які повинні виконатись. У цьому випадку компілятор знає, що Nothing-функція згенерує виключну ситуацію і рядки після цієї функції не будуть виконуватись. Рядки, що виконуються після виклику Nothing-функції, використовують результат виконання цієї функції, тому їх ще не можна виконувати аж до моменту, поки ця функція не буде допрацьована.

Приклад. У прикладі реалізована функція, яка повертає тип Nothing.

import sun.reflect.generics.reflectiveObjects.NotImplementedException

// Функція, яка повертає тип Nothing
fun MyNothingFun(number:Int) : Nothing {
  print(number)
  return throw NotImplementedError("MyNotFun error")
}

fun main(args:Array<String>)
{
  // Виклик функції MyNothingFun() згенерує виключну ситуацію
  MyNothingFun(25)

  // Тут компілятор видає, що цей код не буде виконуватись: "Unreachable code"
  print("Hello world!")
  print("bestprog.net")
}

Виконання вищенаведеного коду генерує виключну ситуацію

Exception in thread "main" kotlin.NotImplementedError: MyNotFun error
at MyClass01Kt.MyNothingFun(MyClass01.kt:19)
25   at MyClass01Kt.main(MyClass01.kt:28)

Проаналізувавши код функції main() у прикладі, можна зробити висновок, що після функції MyNothingFun() рядки виведення (print(…)) виконуватись не будуть. Це дає додаткову інформацію розробнику (нагадування) про необхідність доопрацювання функції MyNothingFun().

 


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