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().

 


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