7
votes

Comment construire idiomatiquement struct avec des références de tas?

Donc, je suis actuellement excentré sur l'initialisation d'un struct code> en chargement d'un fichier yaml code> en mémoire de tas:

p>

extern crate yaml_rust;

use std::io::prelude::*;
use std::fs;
use yaml_rust::{Yaml, YamlLoader};

struct Petrovich {
    middlename: Yaml,
    firstname: Yaml,
    lastname: Yaml
}

impl  Petrovich {

    fn new() -> Petrovich {

        // Open Rules File (Panics on error)
        let mut f = fs::File::open("./src/rules.yml").unwrap();
        // Create String Buffer and Read to it
        let mut buffer = String::new();
        f.read_to_string(&mut buffer).unwrap();
        // Pass Buffer to Yaml and unwrap
        let rules: &Yaml = &YamlLoader::load_from_str(&buffer).unwrap()[0];

        // Return Petrovich with preloaded rules
        Petrovich { 
            middlename: rules["middlename"],
            firstname: rules["firstname"],
            lastname: rules["lastname"]
        }
    }
}


0 commentaires

3 Réponses :


3
votes

Vous essayez de sortir d'un pointeur emprunté (car règles [str] renvoie un & yaml ), mais ce n'est pas légal. Nous devons utiliser des fonctions qui nous permettent de déplacer une valeur hors de l'objet principal YAML . Cela modifiera l'objet principal yaml , mais c'est ok ici, car nous allons le jeter à la fin de la fonction.

Tout d'abord, nous devons comprendre ce que l'indexation avec une chaîne. de mise en œuvre renvoie uniquement une valeur significative Si la valeur est une hache et accède à la valeur sous-jacente en construisant une valeur yaml :: string pour indexer le hachage.

Le YAML :: hachage Variante enveloppe un Btreemap . La bibliothèque fournit la méthode as_hash de la commodité pour y accéder, mais cela ne donne qu'un pointeur immuable. Nous devons utiliser la correspondance de motif pour obtenir un pointeur mutable.

Suivant, nous utiliserons le Supprimer méthode sur le Btreemap Pour extraire la valeur associée aux clés qui nous intéressent.

Voici le résultat: xxx

Notez que ce code paniquera dans des situations dans lesquelles votre code d'origine (si cela fonctionne) ne serait pas, comme vous obtiendrait badvalue s à la place. Je vous laisserai à vous de gérer les erreurs dont vous avez besoin.


0 commentaires

2
votes

YAML code> est clone code>, vous pouvez donc simplement appeler .clone () sur la référence pour copier son contenu "OUT":

    Petrovich { 
        middlename: rules["middlename"].clone(),
        firstname: rules["firstname"].clone(),
        lastname: rules["lastname"].clone(),
    }


0 commentaires

2
votes

J'ai récemment mis en œuvre SERDE Prise en charge de YAML: https://github.com/dtolnay/serde-yaml

SERDE est un puissant cadre de sérialisation qui permet de convertir les structures de rouille. A partir d'une variété de formats: JSON, YAML, XML, TOML, MessagePack, BUCCODE.

Voici un exemple de travail complet qui démontre la désérialisation d'un pétrovitch à partir d'une règle de fichier.yml: < PRE> XXX

SERDE prend en charge des types imbriqués de manière arbitraire compliquée, de sorte que la structure que vous désérialisez pourrait contenir des vecteurs, des cartes ou d'autres structures à l'intérieur et que le code resterait aussi simple.


1 commentaires

Cela fonctionne-t-il sur des versions de rouille stables, ou seulement la nuit?