question sur rust

ref et rc<>

a marqué ce sujet comme résolu.

bonjour, j’avais quelques questions sur 2 points en rust qui me semblent assez obscurs : tout d’abord, j’ai vu quelquefois dans certains codes le mor clef réf. du coup je me demandais quelle est la différence entre ces 2 lignes de code et si il est préférable den utiliser une : let u = &c let ref u =c

de plus, si qqn pouvait m’expliquer l’utilité des pointeurs intelligent Rc<> et Arc<> ça serait cool

Merci d’avance !

Salut,

De ce que j’en comprend :

ref te permet d’emprunter la variable, tu n’en es donc pas propriétaire, mais le type reste le même, alors que & a un type différent.

let c : String = String::new("exemple");
let u = &c; // a un type &String
let ref w = c // a un type String

Quant à Rc, il s’agit de partager une ressource. Par exemple, disons que tu as une classe de sortie audio, et que tu as plusieurs classes de source audio, tu ne vas instancier qu’une seule fois ta sortie audio et la partager entre les sources pour qu’ils y aient accès et se partage la propriété. Ainsi, tant qu’une de ces sources existent (autrement dit tant que tu utilises ta sortie audio), l’instance de ta sortie audio existera. Quand toutes les sources seront détruites, ta sortie audio aussi.

Et Arc est la version thread-safe de Rc. ça sert à la même chose, avoir une instance partagée entre plusieurs propriétaires, mais dans un contexte où les propriétaires peuvent être dans dans threads différents et donc avoir potentiellement un accès concurrent à la ressource partagée.

+0 -1

Salut,

ref te permet d’emprunter la variable, tu n’en es donc pas propriétaire, mais le type reste le même, alors que & a un type différent.

Ça n’a absolument aucun sens. Si le type restait le même, l’état d’ownership serait aussi le même… :-° Il n’y a pas de différence entre let u = &c et let ref u = c, dans les deux cas on se retrouve avec u qui est une référence vers c.

Quand on a déjà un binding vers une valeur (comme c) et qu’on veut une référence vers cette valeur, on préfère utiliser &c pour construire la référence (la forme let ref u = c est d’ailleurs levée par clippy comme étant non-idiomatique). ref u est utile lorsqu’on fait du pattern matching plus avancé et qu’on veut directement obtenir une référence à partir d’une valeur owned. Par exemple :

let a = Some(5u8);
if let Some(ref b) = a {}

permet d’obtenir b comme une référence &u8 vers le 5 contenu dans a.

Quant à Rc, il s’agit de partager une ressource. Par exemple, disons que tu as une classe de sortie audio, et que tu as plusieurs classes de source audio, tu ne vas instancier qu’une seule fois ta sortie audio et la partager entre les sources pour qu’ils y aient accès et se partage la propriété. Ainsi, tant qu’une de ces sources existent (autrement dit tant que tu utilises ta sortie audio), l’instance de ta sortie audio existera. Quand toutes les sources seront détruites, ta sortie audio aussi.

Il n’y a pas de classes en Rust… Ensuite, pour partager une ressource, on a déjà des références qui sont garanties valides. Pour être moins flou, le but de Rc est de déplacer la question de la résolution des lifetimes au runtime plutôt qu’au compile time. On parle parfois de shared owernship, parce que plutôt que d’avoir un seul propriétaire d’une ressource quelconque qui contrôle statiquement sa durée de vie et plein de références simples, on wrappe cette ressource dans un Rc qu’on peut ensuite cloner à loisir. Quand on clone un Rc, on se retrouve en apparence avec une nouvelle valeur qui nous appartient complètement, mais en fait la ressource n’est pas clonée en mémoire. Chaque Rc est un pointeur vers la même zone mémoire, et la résolution de la durée de vie de la ressource pointée se fait au runtime lorsque le dernier Rc disparaît. C’est très utile lorsqu’une ressource est partagée entre plein d’acteurs et qu’avoir un seul propriétaire et des références simples conduirait à un code beaucoup plus compliqué (voire tout simplement impossible à écrire).

+3 -0

Si le type restait le même, l’état d’ownership serait aussi le même…

adri1

En effet, j’ai mal compris ce que disait

& vs ref

  • & denotes that your pattern expects a reference to an object. Hence & is a part of said pattern: &Foo matches different objects than Foo does.
  • ref indicates that you want a reference to an unpacked value. It is not matched against: Foo(ref foo) matches the same objects as Foo(foo).

Si dans le pattern matching ça ne match pas les mêmes objets, c’est de par le fonctionnement du pattern matching et pas à cause du typage.

pour partager une ressource, on a déjà des références qui sont garanties valides.

adri1

pour partager l’accès à une ressource, oui, mais ça ne te garantie pas qu’elle soit présente. Il faut la unwrap. Elle est valide dans le sens où le unwrap pourra te signaler qu’elle n’est plus là. On peut avoir un design où un manager contrôle la ressource et les autres y ont accès avec des références. C’est un choix de design. Mais osef, la partie importante dans ce message c’était que la propriété est partagée et que la ressource pointée par Rc est détruite lorsque tout les propriétaires des Rc sont détruits.

+0 -0

pour partager l’accès à une ressource, oui, mais ça ne te garantie pas qu’elle soit présente. Il faut la unwrap. Elle est valide dans le sens où le unwrap pourra te signaler qu’elle n’est plus là.

Honnêtement je comprends rien à ce que tu essayes de dire… Il n’y a jamais besoin de unwrap une référence pour accéder à l’objet derrière la référence, et ces dernières sont toujours valides. C’est un des points forts de Rust.

la partie importante dans ce message c’était que la propriété est partagée et que la ressource pointée par Rc est détruite lorsque tout les propriétaires des Rc sont détruits.

romantik

Lorsque tous les Rc eux-mêmes sont détruits, plutôt. Un propriétaire d’un Rc pourrait parfaitement choisir de faire fuiter son Rc.

Honnêtement je comprends rien à ce que tu essayes de dire… Il n’y a jamais besoin de unwrap une référence pour accéder à l’objet derrière la référence, et ces dernières sont toujours valides. C’est un des points forts de Rust.

adri1

Ok, je vois. Je mélange les concepts.

Lorsque tous les Rc eux-mêmes sont détruits, plutôt. Un propriétaire d’un Rc pourrait parfaitement choisir de faire fuiter son Rc.

adri1

Oui, tout à fait d’accord, si tu veux être plus précis.


mais du coup qui croire entre vous deux ? :o

phigoldratio

C’est la réponse d’adri1 qui est bonne. Personnellement ça m’a aussi éclairé. Est-ce que sa réponse est suffisamment claire pour toi aussi @phigoldratio ?

+2 -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