Учебники

D Программирование — Функции

В этой главе описываются функции, используемые в D-программировании.

Определение функции в D

Базовое определение функции состоит из заголовка функции и тела функции.

Синтаксис

return_type function_name( parameter list ) { 
   body of the function 
}

Вот все части функции —

  • Тип возврата — функция может возвращать значение. Return_type — это тип данных значения, которое возвращает функция. Некоторые функции выполняют нужные операции без возврата значения. В этом случае return_type является ключевым словом void .

  • Имя функции — это фактическое имя функции. Имя функции и список параметров вместе составляют сигнатуру функции.

  • Параметры — параметр похож на заполнитель. Когда вызывается функция, вы передаете значение параметру. Это значение называется фактическим параметром или аргументом. Список параметров относится к типу, порядку и количеству параметров функции. Параметры являются необязательными; то есть функция может не содержать параметров.

  • Тело функцииТело функции содержит набор операторов, которые определяют, что делает функция.

Тип возврата — функция может возвращать значение. Return_type — это тип данных значения, которое возвращает функция. Некоторые функции выполняют нужные операции без возврата значения. В этом случае return_type является ключевым словом void .

Имя функции — это фактическое имя функции. Имя функции и список параметров вместе составляют сигнатуру функции.

Параметры — параметр похож на заполнитель. Когда вызывается функция, вы передаете значение параметру. Это значение называется фактическим параметром или аргументом. Список параметров относится к типу, порядку и количеству параметров функции. Параметры являются необязательными; то есть функция может не содержать параметров.

Тело функцииТело функции содержит набор операторов, которые определяют, что делает функция.

Вызов функции

Вы можете вызвать функцию следующим образом —

function_name(parameter_values)

Типы функций в D

D программирования поддерживает широкий спектр функций, и они перечислены ниже.

  • Чистые функции
  • Nothrow Функции
  • Ссылочные функции
  • Авто Функции
  • Вариадические функции
  • Функции Inout
  • Функции недвижимости

Различные функции описаны ниже.

Чистые функции

Чистые функции — это функции, которые не могут получить доступ к глобальному или статическому изменяемому состоянию, сохраняя их аргументы. Это может позволить оптимизацию, основанную на том факте, что чистая функция гарантированно не изменяет ничего, что не передается ей, и в случаях, когда компилятор может гарантировать, что чистая функция не может изменить свои аргументы, он может включить полную функциональную чистоту, что является гарантией того, что функция всегда будет возвращать один и тот же результат для одних и тех же аргументов).

Live Demo

import std.stdio; 

int x = 10; 
immutable int y = 30; 
const int* p;  

pure int purefunc(int i,const char* q,immutable int* s) { 
   //writeln("Simple print"); //cannot call impure function 'writeln'
   
   debug writeln("in foo()"); // ok, impure code allowed in debug statement 
   // x = i;  // error, modifying global state 
   // i = x;  // error, reading mutable global state 
   // i = *p; // error, reading const global state
   i = y;     // ok, reading immutable global state 
   auto myvar = new int;     // Can use the new expression: 
   return i; 
}

void main() { 
   writeln("Value returned from pure function : ",purefunc(x,null,null)); 
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

Value returned from pure function : 30 

Nothrow Функции

Другие функции не выдают никаких исключений, полученных из класса Exception. Другие функции ковариантны с метательными.

Nothrow гарантирует, что функция не создает никаких исключений.

import std.stdio; 

int add(int a, int b) nothrow { 
   //writeln("adding"); This will fail because writeln may throw 
   int result; 
   
   try { 
      writeln("adding"); // compiles 
      result = a + b; 
   } catch (Exception error) { // catches all exceptions 
   }

   return result; 
} 
 
void main() { 
   writeln("Added value is ", add(10,20)); 
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

adding 
Added value is 30 

Ссылочные функции

Функции Ref позволяют функциям возвращаться по ссылке. Это аналогично параметрам функции ref.

Live Demo

import std.stdio;

ref int greater(ref int first, ref int second) { 
   return (first > second) ? first : second; 
} 
 
void main() {
   int a = 1; 
   int b = 2;  
   
   greater(a, b) += 10;   
   writefln("a: %s, b: %s", a, b);   
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

a: 1, b: 12

Авто Функции

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

Live Demo

import std.stdio;

auto add(int first, double second) { 
   double result = first + second; 
   return result; 
} 

void main() { 
   int a = 1; 
   double b = 2.5; 
   
   writeln("add(a,b) = ", add(a, b)); 
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

add(a,b) = 3.5

Вариадические функции

Функции Variadiac — это те функции, в которых количество параметров для функции определяется во время выполнения. В C есть ограничение наличия хотя бы одного параметра. Но в D-программировании такого ограничения нет. Простой пример показан ниже.

Live Demo

import std.stdio;
import core.vararg;

void printargs(int x, ...) {  
   for (int i = 0; i < _arguments.length; i++) {  
      write(_arguments[i]);  
   
      if (_arguments[i] == typeid(int)) { 
         int j = va_arg!(int)(_argptr); 
         writefln("\t%d", j); 
      } else if (_arguments[i] == typeid(long)) { 
         long j = va_arg!(long)(_argptr); 
         writefln("\t%d", j); 
      } else if (_arguments[i] == typeid(double)) { 
         double d = va_arg!(double)(_argptr); 
         writefln("\t%g", d); 
      } 
   } 
}
  
void main() { 
   printargs(1, 2, 3L, 4.5); 
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

int 2 
long 3 
double 4.5

Функции Inout

Inout может использоваться как для параметров, так и для возвращаемых типов функций. Это как шаблон для непостоянных, постоянных и неизменных. Атрибут mutable выводится из параметра. Значит, inout переводит выведенный атрибут изменчивости в тип возвращаемого значения. Простой пример, показывающий, как меняется изменчивость, показан ниже.

Live Demo

import std.stdio;

inout(char)[] qoutedWord(inout(char)[] phrase) { 
   return '"' ~ phrase ~ '"';
}

void main() { 
   char[] a = "test a".dup; 

   a = qoutedWord(a); 
   writeln(typeof(qoutedWord(a)).stringof," ", a);  

   const(char)[] b = "test b"; 
   b = qoutedWord(b); 
   writeln(typeof(qoutedWord(b)).stringof," ", b); 

   immutable(char)[] c = "test c"; 
   c = qoutedWord(c); 
   writeln(typeof(qoutedWord(c)).stringof," ", c); 
} 

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —

char[] "test a" 
const(char)[] "test b" 
string "test c"

Функции недвижимости

Свойства позволяют использовать функции-члены, такие как переменные-члены. Он использует ключевое слово @property. Свойства связаны со связанной функцией, которая возвращает значения в соответствии с требованием. Простой пример для свойства показан ниже.

Live Demo

import std.stdio;

struct Rectangle { 
   double width; 
   double height;  

   double area() const @property {  
      return width*height;  
   } 

   void area(double newArea) @property {  
      auto multiplier = newArea / area; 
      width *= multiplier; 
      writeln("Value set!");  
   } 
}

void main() { 
   auto rectangle = Rectangle(20,10); 
   writeln("The area is ", rectangle.area);  
   
   rectangle.area(300); 
   writeln("Modified width is ", rectangle.width); 
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —