IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Rust Discussion :

Problème Borrowing et lifetime (encore un :-D)


Sujet :

Rust

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Janvier 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique

    Informations forums :
    Inscription : Janvier 2018
    Messages : 22
    Par défaut Problème Borrowing et lifetime (encore un :-D)
    Bonjour à tous je suis toujours débutant en Rust car je l'apprend sur mon temps libre, et j'ai un problème de lifetime dont je n'arrive pas à résoudre l'issue
    Voici mon code de novice. je souhaite récupérer les lignes dans un fichier texte (3e partie de mon code) afin de les placer dans un vecteur et là ... c'est le drame

    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    use std::path::Path;
    use std::fs::File;
    use std::io::{prelude::*,BufReader,BufRead};
    use std::io;
    use std::fs;
     
    fn main(){
     
        //1 vérification de l'existence du fichier fichier_texte.txt
        let b = Path::new("fichier_texte.txt").is_file();
        let mut taille_fichier = 0;
        let mut v_message = Vec::new();
     
     
        //2 si le fichier existe on regarde sa taille 
        if b {
            //utilisation des métadatas pour avoir la taille du fichier afin de savoir s'il contient des lignes
            let metadata = fs::metadata("fichier_texte.txt").expect("nop, didn't found!");
            taille_fichier = metadata.len();
            }
     
        //3 enfin si fichier n'existe pas, ou s'il est vide et on en crée un
        if !b || taille_fichier == 0 { let mut new_message= File::create("fichier_texte.txt").expect("nop, not work");
                println!("Alors, quel est ton mot ?");
                let mut entree = String::new();
                io::stdin().read_line(&mut entree).expect("I can't read the entry");
                write!(new_message,"{}",entree).expect("sorry dude!");
              }
     
        //lecture des messages dans le fichier
        let reader = BufReader::new(File::open("fichier_texte.txt").expect("I can't do this"));
          for line in reader.lines() {
            for message_ligne in  line.unwrap().split_whitespace() {                                                 // <-- temporary value dropped while borrowed       
     
                v_message.push(message_ligne);                                                                          // <-- temporary value dropped while borrowed
     
                // test de variable
                println!("word '{}'", message_ligne);
            }
        }
     
     
    }

    Voila si quelqu'un peut m'aider à trouver et comprendre la solution je lui en serait très reconnaissant
    Merci à vous

  2. #2
    Membre Expert
    Avatar de Pyramidev
    Homme Profil pro
    Tech Lead
    Inscrit en
    Avril 2016
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Tech Lead

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 515
    Par défaut
    Bonjour,

    Réponse courte :

    Ça compile en remplaçant v_message.push(message_ligne); par v_message.push(String::from(message_ligne)); ou, ce qui revient au même, par v_message.push(message_ligne.to_owned());.

    Réponse longue, car c'est important de comprendre :

    Le code suivant compile et s'exécute :
    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    fn main(){
        let mut words = Vec::new();
        let my_string = String::from("I am here");
        for word in my_string.split_whitespace() {     
            words.push(word);
        }
        println!("{:?}", words);
    }

    Par contre, le code suivant :
    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    fn main(){
        let mut words = Vec::new();
        {
            let my_string = String::from("I am here");
            for word in my_string.split_whitespace() {     
                words.push(word);
            }
        }
        println!("{:?}", words);
    }

    a une erreur de compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    error[E0597]: `my_string` does not live long enough
     --> src/main.rs:5:21
      |
    5 |         for word in my_string.split_whitespace() {     
      |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough
    ...
    8 |     }
      |     - `my_string` dropped here while still borrowed
    9 |     println!("{:?}", words);
      |                      ----- borrow later used here
    Pour la même raison, le code suivant :
    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    fn main(){
        let mut words = Vec::new();
        for word in String::from("I am here").split_whitespace() {     
            words.push(word);
        }
        println!("{:?}", words);
    }

    a une erreur de compilation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    error[E0716]: temporary value dropped while borrowed
     --> src/main.rs:3:17
      |
    3 |     for word in String::from("I am here").split_whitespace() {     
      |                 ^^^^^^^^^^^^^^^^^^^^^^^^^ creates a temporary which is freed while still in use
    4 |         words.push(word);
    5 |     }
      |     - temporary value is freed at the end of this statement
    6 |     println!("{:?}", words);
      |                      ----- borrow later used here
      |
      = note: consider using a `let` binding to create a longer lived value
    La méthode String::split_whitespace retourne un itérateur. Quand on itère, on ne récupère pas des objets String::from("I"), String::from("am") et String::from("here"), mais des références vers des morceaux de la chaîne String::from("I am here") de départ.

    Du coup, ce qui est ajouté dans le vecteur, ce sont des références. Mais alors cela nécessite que la chaîne String("I am here") référencée vive assez longtemps.

    Dans ton cas, pour gérer la mémoire, tu as plusieurs solutions.

    Une première possibilité est de lire d'un coup tout le fichier et de le stocker dans une String avec std::fs::read_to_string. Alors, tu peux stocker des références vers des morceaux de cette chaîne dans ton vecteur. Tant que ton vecteur n'a pas besoin de vivre plus longtemps que cette grande String, il n'y a pas de problème.

    Une autre possibilité est d'utiliser un vecteur de String. Par exemple, le code suivant compile et s'exécute :
    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    fn main(){
        let mut words = Vec::new();
        for word in String::from("I am here").split_whitespace() {     
            words.push(String::from(word));
        }
        println!("{:?}", words);
    }

  3. #3
    Membre averti
    Homme Profil pro
    Auditeur informatique
    Inscrit en
    Janvier 2018
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Auditeur informatique

    Informations forums :
    Inscription : Janvier 2018
    Messages : 22
    Par défaut Merci


    C'est vraiment super gentil d'avoir pris le temps de m'expliquer, c'est vraiment plus clair maintenant.

    Bonne journée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de design (oui encore)
    Par fanzilan dans le forum Langage
    Réponses: 13
    Dernier message: 02/09/2021, 16h34
  2. Encore des problèmes avec le BDE
    Par Flint dans le forum C++Builder
    Réponses: 19
    Dernier message: 31/12/2007, 23h26
  3. Petit problème de liste déroulante (encore un)
    Par kabal dans le forum Struts 1
    Réponses: 7
    Dernier message: 10/12/2006, 15h08
  4. Réponses: 8
    Dernier message: 10/08/2004, 11h49
  5. Encore un probléme de date avec TADO !
    Par bNoureddine dans le forum Bases de données
    Réponses: 2
    Dernier message: 22/02/2004, 18h22

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo