D Programação - Modelos
Os modelos são a base da programação genérica, que envolve escrever código de maneira independente de qualquer tipo específico.
Um modelo é um projeto ou fórmula para criar uma classe ou função genérica.
Os modelos são o recurso que permite descrever o código como um padrão, para que o compilador gere o código do programa automaticamente. Partes do código-fonte podem ser deixadas para o compilador para serem preenchidas até que essa parte seja realmente usada no programa. O compilador preenche as partes ausentes.
Template de Função
Definir uma função como um modelo é deixar um ou mais dos tipos que ela usa como não especificado, a ser deduzido posteriormente pelo compilador. Os tipos que não foram especificados são definidos na lista de parâmetros do modelo, que fica entre o nome da função e a lista de parâmetros da função. Por esse motivo, os modelos de função têm duas listas de parâmetros -
- lista de parâmetros de modelo
- lista de parâmetros de função
import std.stdio;
void print(T)(T value) {
writefln("%s", value);
}
void main() {
print(42);
print(1.2);
print("test");
}
Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -
42
1.2
test
Modelo de função com vários parâmetros de tipo
Pode haver vários tipos de parâmetros. Eles são mostrados no exemplo a seguir.
import std.stdio;
void print(T1, T2)(T1 value1, T2 value2) {
writefln(" %s %s", value1, value2);
}
void main() {
print(42, "Test");
print(1.2, 33);
}
Se compilarmos e executarmos o código acima, isso produzirá o seguinte resultado -
42 Test
1.2 33
Modelos de classes
Assim como podemos definir modelos de função, também podemos definir modelos de classe. O exemplo a seguir define a classe Stack e implementa métodos genéricos para enviar e retirar os elementos da pilha.
import std.stdio;
import std.string;
class Stack(T) {
private:
T[] elements;
public:
void push(T element) {
elements ~= element;
}
void pop() {
--elements.length;
}
T top() const @property {
return elements[$ - 1];
}
size_t length() const @property {
return elements.length;
}
}
void main() {
auto stack = new Stack!string;
stack.push("Test1");
stack.push("Test2");
writeln(stack.top);
writeln(stack.length);
stack.pop;
writeln(stack.top);
writeln(stack.length);
}
Quando o código acima é compilado e executado, ele produz o seguinte resultado -
Test2
2
Test1
1