Kotlin. Функции. Область видимости функции

Функции. Область видимости функции. Локальная область видимости. Аргументы по умолчанию в параметрах функции

Данная тема является продолжением темы:


Содержание


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

1. Понятие области видимости функции. Локальные переменные. Переменные уровня файла (глобальные переменные)

Каждая объявленная в программе функция имеет свою собственную область видимости. Эта область ограничивается фигурными скобками { }, которые определяют тело функции. В теле функции могут использоваться различные имена, которые есть именами параметров, переменных, констант или иных функций. Исходя из этого контекста, в функции компилятор различает два вида имен переменных (констант):

  • имена уровня файла (глобальные переменные, константы). Это могут быть, например, имена констант, объявленных вне функции. Более подробно об использовании констант в программе можно прочитать здесь. Переменные уровня файла должны быть инициализированы сразу после их объявления. Эти переменные видимы в любом месте проекта и существуют пока не завершится выполнение всей программы;
  • локальные имена. Такие имена являются именами локальных переменных, объявленных в теле функции. Относительно локальной переменной используют термин время жизни переменной. Если в теле функции объявлена переменная, то эта переменная имеет время жизни от момента объявления до закрывающей скобки }.

Ниже приведен пример, объясняющий область видимости локальной переменной.

// Область видимости функции
fun MyFun() { // Тело функции.

  // Здесь объявляются локальные переменные
  var x : Double // объявление локальной переменной x

  // использование локальной переменной x
  x = 2.85

  // ...

} // окончание существования локальной переменной x

В вышеприведенном коде переменная x является локальной. Время жизни переменной x продолжается с момента объявления до закрывающей скобки функции. За пределами тела функции переменная x прекращает свое существование.

 

2. Пример, демонстрирующий использование в теле функции переменных уровня файла и локальных переменных

В примере объявляется функция VolumeSphere(), которая возвращает объем шара на основе его радиуса. В функции используются:

  • переменная уровня файла — константа Pi;
  • локальная переменная volume, которая используется для хранения результата вычисления.

Также в функции используется параметр radius, который имеет такую же область видимости как локальная переменная volume.

 

// Переменная уровня файла
const val Pi = 3.1415

// Функция, вычисляющая объем шара по заданному радиусу
fun VolumeSphere(radius : Double):Double {
  val volume : Double // локальная переменная
  volume = 4.0/3*Pi*radius*radius*radius
  return volume
}

fun main(args:Array<String>)
{
  // Использование функции VolumeSphere()

  // 1. Объявить переменные
  val r : Double
  val result : Double

  // 2. Ввести радиус
  print("radius = ")
  r = readLine().toString().toDouble()

  // 3. Вызвать функцию
  result = VolumeSphere(r)

  // 4. Вывести результат
  print("result = " + result)
}

Тестовый пример

radius = 3.5
result = 179.58908333333332

 

3. Аргументы по умолчанию. Особенности использования

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

Следовательно, значения по умолчанию, устанавливаемые для параметров функции при ее объявлении, называются аргументами по умолчанию.

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

fun FuncName(paramName : Type = value) : Type {
  // ...
}

здесь

  • FuncName – имя функции;
  • paramName – имя параметра;
  • Type – тип параметра;
  • value – значение по умолчанию, которое получает параметр paramName.

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

FuncName(argument)

Другой способ – вызов без аргумента

FuncName()

При этом способе, вместо аргумента, в теле функции подставляется значение value, которое указано в параметре paramName при объявлении функции

paramName : Type = value

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

fun FuncName(paramName1 : Type1 = value1,
             paramName2 : Type2 = value2,
             ...
             paramNameN : TypeN = valueN,
            ) : Type {
  // ...
}

здесь

  • paramName1, paramName2, paramNameN – имена параметров, которые имеют соответственно типы Type1, Type2, TypeN и получают соответственно значения value1, value2, valueN.

 

4. Ограничения на применение аргументов по умолчанию

При объявлении функции с несколькими аргументами по умолчанию, нужно придерживаться следующего правила: первыми следуют параметры, не получающие значений по умолчанию, после этого следуют параметры, которые получают значения по умолчанию. Дело в том, что компилятор в любом случае передает первый переданный аргумент первому параметру. А это значит, что второй, или иной следующий параметр не будет получать никакого значения, что будет приводить к ошибке на этапе компиляции.

Например.

Пусть задано следующее ошибочное объявление функции

fun MyFun(param1 : Int = 2, param2 : Double) {
  println(param1)
  println(param2)
}

В этом случае вызов функции MyFun() ограничен

... 
MyFun(3, 2.2) // Работает, оба параметра принимают значение.
MyFun()  // Ошибка. Нужно задать param2.
MyFun(2) // Ошибка. Задается значение param1. Значение param2 неопределено. ...

 

5. Примеры объявления и использования функций, содержащих аргументы по умолчанию
5.1. Вычисление расстояния между двумя точками

Задача. Разработать и продемонстрировать работу функции, вычисляющей расстояние между двумя точками заданных координатами (x1; y1) и (x2; y2). При объявлении функции задать следующие значения точек по умолчанию

x1 = 0
y1 = 0
x2 = 1
y2 = 1

Решение.

// Функция, которая вычисляет расстояние между двумя точками,
// заданными координатами (x1; y1), (x2; y2).
fun Length(x1 : Double = 0.0, y1 : Double = 0.0,
    x2 : Double = 1.0, y2 : Double = 1.0) : Double {
  return Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
}

fun main(args:Array<String>)
{
  // Демонстрация использования функции Length()

  // Вычислить длину для точек (0, 0), (1, 1)
  println("(0,0)-(1,1) = " + Length())

  // Вычислить длину для точек (0, 0), (2, 2)
  println("(0,0)-(2,2) = " + Length(0.0, 0.0, 2.0, 2.0))

  // Вычислить длину для точек (3, 4), (1, 1)
  println("(3,4)-(1,1) = " + Length(3.0, 4.0))

  // Вычислить длину для точек (2, 0), (1, 1)
  println("(2,0)-(1,1) = " + Length(2.0))
}

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

(0,0)-(1,1) = 1.4142135623730951
(0,0)-(2,2) = 2.8284271247461903
(3,4)-(1,1) = 3.605551275463989
(2,0)-(1,1) = 1.4142135623730951

 

5.2. Модуль комплексного числа

Задача. Реализовать функцию AbsComplex(), которая получает параметрами действительную и мнимую части комплексного числа. Параметры функции получают единичные значения по умолчанию.

Решение.

// Функция, вычисляющая модуль комплексного числа
fun AbsComplex(re:Double = 1.0, im:Double = 1.0) : Double {
  return Math.sqrt(re*re+im*im)
}

fun main(args:Array<String>)
{
  // Демонстрация использования функции AbsComplex()

  // Вычислить модуль комплексного числа 1 + 1*j
  println("|1 + j| = " + AbsComplex())

  // Модуль числа 3 - 2*j
  println("|3 - 2*j| = " + AbsComplex(3.0,-2.0))

  // Модуль числа 2 + j
  println("|2 + 1*j| = " + AbsComplex(2.0))

  // Модуль числа 1 + 2*j
  println("|1 + 2*j| = " + AbsComplex(1.0, 2.0))
}

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

|1 + j| = 1.4142135623730951
|3 - 2*j| = 3.605551275463989
|2 + 1*j| = 2.23606797749979
|1 + 2*j| = 2.23606797749979

 


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