Programación D - Funciones
Este capítulo describe las funciones utilizadas en la programación D.
Definición de función en D
Una definición de función básica consta de un encabezado de función y un cuerpo de función.
Sintaxis
return_type function_name( parameter list ) {
body of the function
}
Aquí están todas las partes de una función:
Return Type- Una función puede devolver un valor. losreturn_typees el tipo de datos del valor que devuelve la función. Algunas funciones realizan las operaciones deseadas sin devolver un valor. En este caso, return_type es la palabra clavevoid.
Function Name- Este es el nombre real de la función. El nombre de la función y la lista de parámetros juntos constituyen la firma de la función.
Parameters- Un parámetro es como un marcador de posición. Cuando se invoca una función, se pasa un valor al parámetro. Este valor se conoce como parámetro o argumento real. La lista de parámetros se refiere al tipo, orden y número de parámetros de una función. Los parámetros son opcionales; es decir, una función puede no contener parámetros.
Function Body - El cuerpo de la función contiene una colección de declaraciones que definen lo que hace la función.
Llamar a una función
Puede llamar a una función de la siguiente manera:
function_name(parameter_values)
Tipos de funciones en D
La programación D admite una amplia gama de funciones y se enumeran a continuación.
- Funciones puras
- Funciones de Nothrow
- Funciones de referencia
- Funciones automáticas
- Funciones variadas
- Funciones de Inout
- Funciones de propiedad
Las diversas funciones se explican a continuación.
Funciones puras
Las funciones puras son funciones que no pueden acceder al estado mutable global o estático salvo a través de sus argumentos. Esto puede habilitar optimizaciones basadas en el hecho de que se garantiza que una función pura no mutará nada que no se le pase, y en los casos en que el compilador puede garantizar que una función pura no puede alterar sus argumentos, puede habilitar la pureza funcional completa, que es decir, la garantía de que la función siempre devolverá el mismo resultado para los mismos argumentos).
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));
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
Value returned from pure function : 30
Funciones de Nothrow
Las funciones de Nothrow no arrojan ninguna excepción derivada de la clase Exception. Las funciones de Nothrow son covariantes con las de lanzar.
Nothrow garantiza que una función no emite ninguna excepción.
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));
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
adding
Added value is 30
Funciones de referencia
Las funciones de referencia permiten que las funciones regresen por referencia. Esto es análogo a los parámetros de la función de referencia.
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);
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
a: 1, b: 12
Funciones automáticas
Las funciones automáticas pueden devolver valor de cualquier tipo. No hay restricciones sobre qué tipo se devolverá. A continuación se ofrece un ejemplo sencillo de la función de tipo automático.
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));
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
add(a,b) = 3.5
Funciones variadas
Las funciones Variadiac son aquellas funciones en las que el número de parámetros para una función se determina en tiempo de ejecución. En C, existe la limitación de tener al menos un parámetro. Pero en la programación D, no existe tal limitación. A continuación se muestra un ejemplo sencillo.
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);
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
int 2
long 3
double 4.5
Funciones de Inout
El inout se puede utilizar tanto para parámetros como para tipos de funciones de retorno. Es como una plantilla para mutable, constante e inmutable. El atributo de mutabilidad se deduce del parámetro. Significa que inout transfiere el atributo de mutabilidad deducido al tipo de retorno. A continuación se muestra un ejemplo sencillo que muestra cómo se cambia la mutabilidad.
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);
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
char[] "test a"
const(char)[] "test b"
string "test c"
Funciones de propiedad
Las propiedades permiten usar funciones miembro como variables miembro. Utiliza la palabra clave @property. Las propiedades están vinculadas con una función relacionada que devuelve valores según los requisitos. A continuación se muestra un ejemplo sencillo de propiedad.
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);
}
Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:
The area is 200
Value set!
Modified width is 30