union rust

a quoi servent les unions ?

a marqué ce sujet comme résolu.

Salut,

Ta question est "à quoi ça sert ?". Doit-on comprendre que tu as compris comment ça fonctionne / son effet ?

L’effet, en bref, c’est que les champs qui composent l’union partage la même zone mémoire, donc si on modifie l’un, les autres champs auront par conséquent changé de valeur. Par exemple, si l’union u est composé d’un i16 i et d’un u16 u, et sa valeur est 2 alors u.i == 2 && u.u == 2. Maintenant j’affecte -1 à i et j’obtiens u.i == -1 && u.u == 65535.
(Je suis resté en textuel car les accès à ces champs en rust est toujours unsafe d’après la doc)

Pour ce qui est de "à quoi ça sert", il est vrai que c’est quand même très particulier. Pour réinterprêter des données on a d’autres outils, comme as.
Il se trouve que l’union est un outil qui existe aussi en C. Et dans ce langage, j’ai eu une utilisation d’union qui me semblais appropriée et qui doit pouvoir aussi se justifier en rust : il s’agissait de trame réseaux.
Les trames réseaux, qui véhiculent les informations de communication, économisent un maximum de bit pour se limiter à ce qui est utile et obtenir ainsi un maximum de débit. Alors lorsqu’un champs ne peut avoir que 4 valeurs par exemple, comme un enum ou un compteur borné, on va lui réserver seulement 2 bits. Mais derrière, l’ordinateur, lui, il sait travailler en groupe d’octet. Dans la mémoire, mes 2 bits sont noyé au milieu d’un octet qui comporte les infos des champs voisins. Donc on peut déclarer des unions entre des groupes d’octets qui contiennent la trame entièrement et des structures décrivant le protocole (généralement composé de bit-fields pour pouvoir récupérer mon enum sur 2 bits uniquement) qui servent de "grille de lecture" pour pouvoir exploiter les données de la trame.

C’est la seule utilisation que j’ai expérimenté (et c’était en C) mais rust est un langage qui veut proposer une gestion fine de la mémoire, et les domaines comme la programmation système ou le réseau ont parfois besoin de faire coïncider des zones mémoires.

+0 -0

L’exemple le plus courant (citation needed) est probablement pour avoir une variable au typage dynamique dans un langage au typage statique (comme le C). Un exemple très basique :

struct Type {
    int type;
    union {
        int i;
        char* str;
        float f;
    };
};

Pourquoi payer l’espace mémoire de 3 types (int, float, et char*) quand il n’y en a qu’un seul d’utilisé à la fois ? Tu mets tout en une union et donc la taille prise est la taille du plus gros élément (plutôt que la somme des trois). Le champ "type" est là pour savoir quel champ est utilisé.

Salut,

Les deux messages précédents ratent complètement le point principal des union en Rust, qui est de faciliter l’interfaçage avec du code C qui manipule des unions en C (qui ressemblent fortement aux unions de Rust). Dans du code Rust normal qui ne s’interface pas avec du C, il est extrêmement rare d’avoir besoin d’utiliser des unions (pour ne pas dire jamais…).

Si on veut manipuler des trames réseaux en Rust, il n’y a pas de raison de s’emmerder avec des unions. On manipulerait plutôt soit un type qui wrappe la trame et donne une API safe autour, soit des types variés pour les différents morceaux des trames qui implémentent correctement la façon de s’écrire dans une trame. (Et probablement les deux, même).

Pour ce qui est de l’exemple de faire du "typage dynamique" (sic), c’est encore plus tiré par les cheveux… :-° Une enum remplacerait l’exemple donné (qui n’a rien à voir avec du typage dynamique) de façon beaucoup plus facile et safe à manipuler, et pour faire du typage dynamique on a dyn Trait.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte