Quelle est la façon correcte d'utiliser la durée de vie avec un struct dans la Rouille?
Je veux écrire cette structure:
struct A {
b: B,
c: C,
}
struct B {
c: &C,
}
struct C;
La B.c
doit être emprunté auprès de la A.c
.
A ->
b: B ->
c: &C -- borrow from --+
|
c: C <------------------+
C'est ce que j'ai essayé:
struct C;
struct B<'b> {
c: &'b C,
}
struct A<'a> {
b: B<'a>,
c: C,
}
impl<'a> A<'a> {
fn new<'b>() -> A<'b> {
let c = C;
A {
c: c,
b: B { c: &c },
}
}
}
fn main() {}
Mais il échoue:
error[E0597]: `c` does not live long enough
--> src/main.rs:17:24
|
17 | b: B { c: &c },
| ^ borrowed value does not live long enough
18 | }
19 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the lifetime 'b as defined on the method body at 13:5...
--> src/main.rs:13:5
|
13 | fn new<'b>() -> A<'b> {
| ^^^^^^^^^^^^^^^^^^^^^
error[E0382]: use of moved value: `c`
--> src/main.rs:17:24
|
16 | c: c,
| - value moved here
17 | b: B { c: &c },
| ^ value used here after move
|
= note: move occurs because `c` has type `C`, which does not implement the `Copy` trait
J'ai lu la Rouille de documentation sur les droits de propriété, mais je ne sais toujours pas comment le résoudre.
Frère de références (c'est à dire, la référence à la partie de la même structure) n'est pas possible dans la Rouille.
OriginalL'auteur Quan Brew | 2014-12-21
Vous devez vous connecter pour publier un commentaire.
Il n'y a effectivement plus d'un raison pour laquelle le code ci-dessus échoue. Nous allons décomposer un peu et explorer quelques options sur la façon de le résoudre.
Laissez-moi d'abord de supprimer la
new
et essayez de construire une instance deA
directement dansmain
, de sorte que vous voyez que la première partie du problème n'a rien à voir avec la durée de vie:cela échoue avec:
ce qu'il dit, c'est que si vous affectez
c1
àc
, vous vous déplacez à sa propriété àc
(c'est à dire que vous ne pouvez pas y accéder plus longtemps grâce àc1
, uniquement par le biais dec
). Cela signifie que toutes les références àc1
ne serait plus valide. Mais vous avez un&c1
toujours dans la portée (B), de sorte que le compilateur ne pouvez pas vous permettre de compiler ce code.Le compilateur fait allusion à une possible solution dans le message d'erreur quand il dit que le type
C
est non-copiable. Si vous pouviez faire une copie d'unC
, votre code peut alors être valable, car l'attribution dec1
àc
serait de créer une nouvelle copie de la valeur au lieu d'aller de propriété de l'original de la copie.Nous pouvons faire
C
copiable par l'évolution de sa définition comme ceci:Maintenant le code ci-dessus fonctionne. Notez que ce @matthieu-m commentaires est toujours vrai: nous ne pouvons pas stocker à la fois la référence à une valeur, et la valeur elle-même en B (nous sommes en conservant une référence à une valeur et une COPIE de la valeur ici). Ce n'est pas juste pour les structures, cependant, c'est comment la propriété des œuvres.
Maintenant, si vous ne voulez pas (ou ne peut pas) faire
C
copiable, vous pouvez stocker des références dans les deuxA
etB
à la place.Tous bon alors? Pas vraiment... on a encore envie de se déplacer à la création de
A
de retour dans unenew
méthode. Et c'est là QUE nous allons lancer en difficulté avec la durée de vie. Passons à la création deA
de retour dans une méthode:comme prévu, voici notre durée de vie d'erreur:
c'est parce que
c1
est détruit à la fin de lanew
méthode, on ne peut donc pas renvoyer une référence.Une solution possible est de créer
C
à l'extérieur denew
et passer comme paramètre:aire de jeux
techniquement, vous pourriez retourner des références avec un statique de la durée de vie (
&'static C
), mais c'est rarement utile dans la pratiqueOriginalL'auteur Paolo Falabella
Après vérification avec Manishearth et eddyb sur le #rouille IRC, je crois qu'il n'est pas possible pour une structure pour stocker une référence à lui-même ou une partie de lui-même. Donc, ce que vous essayez de faire n'est pas possible au sein de la Rouille du type de système.
OriginalL'auteur Rufflewind