Salut,
Les lifetimes en Rust ne sont pas un concept lié à la stack, ou à un quelconque concept qui existe à l’exécution. Et en fait, ils ne sont pas liés non plus directement à la profondeur d’accolades (si on inclut les blocs { }
non-nommés dans cette notion) : les lifetimes étaient étroitement liés à ce type de scope dans les anciennes versions de Rust, ils ne le sont plus vraiment dans les nouvelles (avant, il suffisait de faire des déclarations à l’intérieur d’un bloc non-nommé pour que le compilateur laisse plus ou moins tranquille ce que tu déclares à l’intérieur, maintenant il va plus loin que ça).
Plus généralement, les lifetimes n’existent qu’à la compilation et sont une indication pour le compilateur.
Les lifetimes sont un concept abstrait qui te permet d’effectuer une désambiguïsation à propos de la portée d’un argument de fonction, d’une valeur de retour ou d’un élément de structure. Ils te permettent d’indiquer qu’un identifiant (de variable, d’élément de structure, etc.) vivra au moins aussi longtemps qu’un autre. Cela est surtout utile dans des cas comme ceux-ci :
- Pour s’assurer qu’une valeur de retour, si elle fait référence à par exemple un argument, vit au moins longtemps que cet argument (dans ce cas, les arguments concernés et la valeur de retour devront partager les mêmes lifetimes),
- Pour s’assurer qu’un élément de structure, s’il contient une référence à autre chose, vivra au moins aussi longtemps qu’un autre élément de structure dont il dépend, ou que la structure elle-même, ou qu’un lifetime passé comme générique à la structure, etc.
En effet, dans ces cas-là, le lifetime constituera une aide obligatoire pour que le compilateur comprenne ce que tu veux faire sans trop se prendre la tête et effectue les bonnes vérifications. Il faut comprendre les vérifications de Rust seront suffisamment strictes dans tous les cas pour que ton code soit memory-safe (sauf si tu utilises un mot-clef comme unsafe
ou que tu imbriques du C), simplement, parfois, il faut aiguiller le compilateur pour qu’il comprenne que tu as une raison légitime de faire sortir de ta fonction/structure une référence à une variable qui a été définie à un niveau supérieur, afin qu’il ne soit pas « trop » strict.
Dans les premières versions de Rust, il fallait vraiment spécifier des lifetimes de partout dans les programmes et les fonctions, bien plus que dans les cas que j’ai mentionné ci-dessus, et c’était vraiment peu lisible. Ça s’est amélioré depuis (grâce à la fonctionnalité nommée « lifetime elision », qui désigne le fait de devoir n’en spécifier que dans certains cas, tout simplement).
Concernant le mot-clef 'static
, il désigne plus ou moins ce qui se ramène au mot-clef static
en C, c’est-à-dire des données constantes, en principe en lecture seule et définies à la compilation (cela va correspondre au segment .data
ou .rodata
au niveau ELF).
Bonne journée,