English 中文(简体)
D Programming - Functions
  • 时间:2024-11-03

D Programming - Functions


Previous Page Next Page  

This chapter describes the functions used in D programming.

Function Definition in D

A basic function definition consists of a function header and a function body.

Syntax

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

Here are all the parts of a function −

    Return Type − A function may return a value. The return_type is the data type of the value the function returns. Some functions perform the desired operations without returning a value. In this case, the return_type is the keyword void.

    Function Name − This is the actual name of the function. The function name and the parameter pst together constitute the function signature.

    Parameters − A parameter is pke a placeholder. When a function is invoked, you pass a value to the parameter. This value is referred to as actual parameter or argument. The parameter pst refers to the type, order, and number of the parameters of a function. Parameters are optional; that is, a function may contain no parameters.

    Function Body − The function body contains a collection of statements that define what the function does.

Calpng a Function

You can a call a function as follows −

function_name(parameter_values)

Function Types in D

D programming supports a wide range of functions and they are psted below.

    Pure Functions

    Nothrow Functions

    Ref Functions

    Auto Functions

    Variadic Functions

    Inout Functions

    Property Functions

The various functions are explained below.

Pure Functions

Pure functions are functions which cannot access global or static, mutable state save through their arguments. This can enable optimizations based on the fact that a pure function is guaranteed to mutate nothing which is not passed to it, and in cases where the compiler can guarantee that a pure function cannot alter its arguments, it can enable full, functional purity, that is, the guarantee that the function will always return the same result for the same arguments).

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)); 
}

When the above code is compiled and executed, it produces the following result −

Value returned from pure function : 30 

Nothrow Functions

Nothrow functions do not throw any exceptions derived from class Exception. Nothrow functions are covariant with throwing ones.

Nothrow guarantees that a function does not emit any exception.

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)); 
}

When the above code is compiled and executed, it produces the following result −

adding 
Added value is 30 

Ref Functions

Ref functions allow functions to return by reference. This is analogous to ref function parameters.

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);   
}

When the above code is compiled and executed, it produces the following result −

a: 1, b: 12

Auto Functions

Auto functions can return value of any type. There is no restriction on what type to be returned. A simple example for auto type function is given below.

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)); 
}

When the above code is compiled and executed, it produces the following result −

add(a,b) = 3.5

Variadic Functions

Variadiac functions are those functions in which the number of parameters for a function is determined in runtime. In C, there is a pmitation of having atleast one parameter. But in D programming, there is no such pmitation. A simple example is shown below.

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("	%d", j); 
      } else if (_arguments[i] == typeid(long)) { 
         long j = va_arg!(long)(_argptr); 
         writefln("	%d", j); 
      } else if (_arguments[i] == typeid(double)) { 
         double d = va_arg!(double)(_argptr); 
         writefln("	%g", d); 
      } 
   } 
}
  
void main() { 
   printargs(1, 2, 3L, 4.5); 
}

When the above code is compiled and executed, it produces the following result −

int 2 
long 3 
double 4.5

Inout Functions

The inout can be used both for parameter and return types of functions. It is pke a template for mutable, const, and immutable. The mutabipty attribute is deduced from the parameter. Means, inout transfers the deduced mutabipty attribute to the return type. A simple example showing how mutabipty gets changed is shown below.

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); 
} 

When the above code is compiled and executed, it produces the following result −

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

Property Functions

Properties allow using member functions pke member variables. It uses the @property keyword. The properties are pnked with related function that return values based on requirement. A simple example for property is shown below.

import std.stdio;

struct Rectangle { 
   double width; 
   double height;  

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

   void area(double newArea) @property {  
      auto multipper = newArea / area; 
      width *= multipper; 
      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); 
}

When the above code is compiled and executed, it produces the following result −

The area is 200 
Value set! 
Modified width is 30
Advertisements