Une des façons de définir nos propres types en D
est de définir une struct
:
struct Person
{
int age;
int height;
float ageXHeight;
}
Une struct
est toujours construite sur la pile (à moins
qu'elle soit appelée avec new
) et est copiée par valeur
lorsqu'elle est passée en paramètre à une fonction.
auto p = Person(30, 180, 3,1415);
auto t = p; //copie
Quand un nouvel objet struct
est créé, ses membres peuvent
être initialisés dans l'ordre dans lequel ils sont définis dans
la struct
. On peut définir un constructeur personnalisé en créant
une méthode this(...)
. En cas de conflits de nom, on peut accéder
à la structure courante grâce à this
:
struct Person
{
this(int age, int height)
{
this.age = age;
this.height = height;
this.ageXHeight = cast(float)age * height;
}
}
//...
Person p(30, 100); //initialisation
p = Person(30, 180); //assignation à une nouvelle instance
Une struct
peut contenir n'importe quel nombre de méthodes. Ces méthodes
sont public
par défaut, et donc accessibles depuis l'extérieur. Elles
peuvent être private
et donc n'être accessibles que depuis une autre
méthode de la même struct
, ou d'un autre endroit dans le même module.
struct Person
{
void faireQqch()
{
//...
}
private void faireChosePrivee()
{
//...
}
}
//...
p.faireQqch(); // Appel de la méthode faireQqch
p.faireChosePrivee(); // Interdit
const
Si une méthode est déclarée avec const
, elle ne sera pas autorisée à modifier
un membre de la structure. C'est une garantie offerte par le compilateur.
Déclarer une méthode const
permet de l'appeler sur un objet const
ou immutable
, mais garantie également aux appelants que la méthode ne changera pas l'état de l'objet.
Si une méthode est déclarée static
, on pourra l'appeler sans objet instancié (par exemple Person.methodeStatique()
) mais elle ne sera pas autorisée à accéder à des membres non-statiques. Cela peut être utilisé si une méthode n'a pas besoin d'accéder à un membre non-static de la structure, mais est lié logiquement à cette structure. Cela peut aussi être utilisé pour offrir une fonctionnalité sans créer d'instance explicite, par exemple, certains implémentations du patron de conception Singleton utilisent static
.
Une struct
ne peut pas hériter d'une autre struct
.
Des hiérarchies de types ne peuvent être construites qu'avec des classes,
que nous verrons dans une prochaine aprtie.
Cependant, avec alias this
ou les mixins
, on peut facilement obtenir du polymorphisme.
À partir de struct Vector3
, implémentez les fonctions suivantes et faites fonctionner l'exemple correctement:
length()
- retourne la longueur du vecteur
dot(Vector3)
- retourne le produit scalaire avec ce vecteur
toString()
- retourne la représentation de ce vecteur sous forme de string
La fonction std.string.format
retourne une chaîne de caractères en utilisant une syntaxe similaire à celle de printf
: format("MonEntier = %d", monEntier)
. Les chaînes de caractères seront expliquées plus en détails dans une prochaine partie.