| masklinn |
SekYo a écrit :
Grrr Rust, même après 18 jours d'AoC, y a des trucs qui prennent la tête :o
|
Oui ça s'pas étonnant, l'AoC ça reste un environnement spécial et simpliste :D
SekYo a écrit :
Et pourtant c'est basique :fou: struct Child { pub tables: Vec<i32> } struct Container { pub children: Vec<Child> } impl Container { pub fn new() -> Container { Container { children: Vec::new() } } pub fn update_all_children(&mut self) { for child in self.children.iter_mut() { self.update_child(child); } } pub fn update_child(&self, child: &mut Child) { child.tables.push(99999) } } |
Forcément il me met un "cannot borrow `*self` as immutable because it is also borrowed as mutable" dans mon update_all_children Qqun à une idée de comment je peux faire marcher ça ? (masklinn peut être [:fight]) Alors ça fonctionne si je sors le code de update_child pour le mettre directement dans la boucle du update_all_children, mais mon vrai code est beaucoup plus complexe, j'ai pas envie de me retrouver avec une boucle qui fait 500 LOC :sarcastic: J'ai trouvé des pistes qui parlent d'interior mutability, mais y a pas de solution plus simple que d'encapsuler mon children dans des Rc/Refcell ? :o
|
L'inner mut va effectivement te permettre de passer outre, t'as juste besoin d'un RefCell (pour pouvoir faire un borrow_mut sur children), mais ça semble quand même une idée foireuse, genre ici la signature de `update_child` a jamais de sens, sauf si un conteneur peut mettre à jour l'enfant de quelqu'un d'autre, ce qui semble douteux. Des options que je vois:
- update_all_children et update_child appellent Child::update, qui contient la vraie logique, potentiellement en lui filant du bordel de custo (que tu peux extraire de ton conteneur, tant que ca échappe pas les borrows partiels sont pas un problème, notes que ça marche aussi avec les closures)
- update_child(&mut self, child: usize), et en interne il peut indexer, faire ses accès, tout le bordel, `update_all_children` devient une itération sur les index
- la 3e option c'est la triche ultime (enfin non ça reste les unsafe qui UB) mais c'est pas panic-safe donc faut faire super gaffe avec le contenu de "update_child"
Code :
pub fn update_all_children(&mut self) { let mut orphans = self::mem::take(self.children); for child in orphans.iter_mut() { self.update_child(child); } self.children = orphans; }
| Et note qu'il y a des principes OO qui disent aussi que c'est pas correct de faire ton bordel là (la Loi de Demeter). Donc l'OO confus où tout est toujours mutable c'est pas une esscuse [:_pluto_]
R3g a écrit :
Alors j’y connais rien, j’ai jamais pratiqué ce langage, mais à quoi ça sert de déclarer self mutable dans update_all_children ?
|
T'as besoin d'avoir un self mutable pour pouvoir avoir un accès mutable à ses membres, ici le vecteur "children", et les enfants qui sont dedans. Sans &mut self, pas de iter_mut(), et pas de &mut Child (sauf à passer par mutabilité intérieure) |