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 :

implémentation de Trait dans un module rust


Sujet :

Rust

  1. #1
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut implémentation de Trait dans un module rust
    Bonjour,
    je débute avec Rust et j'ai une erreur dont je ne comprends pas la raison.
    Rust m'indique que ma méthode run() n'ai pas visible dans le scope. Evidement, en suppriment la définition mod { ...} la méthode fonctionne correctement.
    voici le code

    Code : 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
    mod perso {
        #[derive(Debug)]
        pub struct Perso {
            nom : String,
            age : u32,
        }
    
        impl Perso {
            pub fn new(nom : &str, age:u32) -> Perso {
                Perso{nom:nom.to_string(), age}
            }
    
            pub fn grow(&mut self, growing:u32) {
                self.age += growing;
            }
        }
    
        pub trait Move {
            fn run(&self);
        }
    
        impl Move for Perso {
            fn run(&self) {
                println!("perso run !");
            }
        }
    }
    
    fn main() {
        let mut t = perso::Perso::new("michael", 50);
        t.grow(15);
        println!("perso : {:?}",t);
        t.run(); // ERROR :  no method named `run` found for struct `perso::Perso` in the current scope 
    }
    Je comprends bien que rust me dit qu'il ne trouve pas la méthode dans le scope, mais je ne comprends pas pourquoi et comment y remédier.
    Merci de votre aide et bonne journée.

    Bringer

  2. #2
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,

    Citation Envoyé par bringer Voir le message
    Bonjour,
    je débute avec Rust et j'ai une erreur dont je ne comprends pas la raison.
    Rust m'indique que ma méthode run() n'ai pas visible dans le scope. Evidement, en suppriment la définition mod { ...} la méthode fonctionne correctement.
    Votre erreur, vient de votre interface; plus précisément le partage de comportement.
    Pour faire simple, votre module est un espace de noms, c'est comme un conteneur et le trait est une interface que je peux qualifier comme étant une classe abstraite; qui permet d'attribuer des actions supplémentaires à votre personnage.
    Il faut donc, attribuer l'action (function run) à personnage exemple:

    Code rs : 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
    mod personage{
        #[derive(Debug)]
        pub struct Personage{
            name: String,
            age: u32,
        }
        
        impl Personage{
            pub fn new(name: String, age: u32)->Self{
                Personage{
                    name,
                    age,
                }
            }
            
            pub fn grow(&mut self, growing:u32){
                self.age += growing;
            }
        }
    }
    
    
    pub trait Move{
        fn run(&self);
    }
        
    impl Move for personage::Personage{
        fn run(&self){
            println!("Personage run!");
        }
    }
    
    
    fn main(){
        let mut foo = personage::Personage::new(
            "Corsair".to_string(), 100u32);
        foo.grow(100u32);
        println!("Perso:{:?}", foo);
        foo.run();
    }

    à bientôt
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  3. #3
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 109
    Points
    6 109
    Par défaut
    Bonjour bringer,

    Je viens de copier-coller ton code dans https://play.rust-lang.org/ et le message d'erreur complet est :
    Code : 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
    error[E0599]: no method named `run` found for struct `Perso` in the current scope
      --> src/main.rs:33:7
       |
    3  |     pub struct Perso {
       |     ---------------- method `run` not found for this
    ...
    19 |         fn run(&self);
       |            --- the method is available for `Perso` here
    ...
    33 |     t.run(); // ERROR :  no method named `run` found for struct `perso::Perso` in the current scope 
       |       ^^^ method not found in `Perso`
       |
       = help: items from traits can only be used if the trait is in scope
    help: the following trait is implemented but not in scope; perhaps add a `use` for it:
       |
    1  | use crate::perso::Move;
       |
     
    For more information about this error, try `rustc --explain E0599`.
    Note le passage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
       = help: items from traits can only be used if the trait is in scope
    help: the following trait is implemented but not in scope; perhaps add a `use` for it:
       |
    1  | use crate::perso::Move;
       |
    Effectivement, si j'ajoute la ligne suivante, ça compile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    use crate::perso::Move;
    Par exemple, tu peux la mettre là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    use crate::perso::Move;
     
    fn main() {
    Remarque : cela marche aussi en écrivant :

  4. #4
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Bonjour Sambia39,
    Merci pour ta réponse. Je comprends bien le point de vue, mais dans mon exemple, le trait Move est intégré au module, en attendant éventuellement que le module soit transféré dans son fichier propre.
    De fait, comme le mentionne en dessous Pyramidev, la solution que j'avais également trouvé était d'ajouté un : use personnage::Move;

    Ce que je ne comprends pas trop, c'est que comme le struct de Personnage est déclaré public (pub struct Personnage), il devient accessible pour le main(), et donc pourquoi en déclarant le trait Move comme public (pub trait Move), lui même n'est-il pas accessible également depuis le main() ?

    Merci pour ton aide et bonne journée.

    Citation Envoyé par Pyramidev Voir le message
    Merci Pyramidev de ta réponse,

    J'étais parti dans la même logique et j'ai finalement ajouté un use personnage::Move dans mon fichier main.rs.
    Comme je l'ai répondu à sambia39 au dessus, ce que je ne comprends pas, c'est pourquoi en déclarant pub struc Personnage, il devient accessible dans le main et que pour le pub trait Move il n'est pas accessible dans le main ?

    Merci de ta réponse et bonne journée.

  5. #5
    Expert éminent
    Avatar de Pyramidev
    Homme Profil pro
    Développeur
    Inscrit en
    Avril 2016
    Messages
    1 471
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur

    Informations forums :
    Inscription : Avril 2016
    Messages : 1 471
    Points : 6 109
    Points
    6 109
    Par défaut
    En fait, même sans écrire use perso::Move;, la méthode run est accessible, mais sous la forme perso::Move::run.
    use perso::Move; permet d'écrire t.run() au lieu de perso::Move::run(&t).

    De même, avec use perso::Perso;, tu pourras écrire Perso::new("michael", 50) au lieu de perso::Perso::new("michael", 50).

  6. #6
    Membre expérimenté
    Avatar de sambia39
    Homme Profil pro
    No Comment
    Inscrit en
    Mai 2010
    Messages
    543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loiret (Centre)

    Informations professionnelles :
    Activité : No Comment
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Mai 2010
    Messages : 543
    Points : 1 745
    Points
    1 745
    Par défaut
    Citation Envoyé par bringer Voir le message

    Ce que je ne comprends pas trop, c'est que comme le struct de Personnage est déclaré public (pub struct Personnage), il devient accessible pour le main(), et donc pourquoi en déclarant le trait Move comme public (pub trait Move), lui même n'est-il pas accessible également depuis le main() ?
    Ok; de mon points de vue, il faut partir du mots-clés "pub". Le mot-clé "pub" appliquer rend la structure ou l'élément sur lequel il est appliqué public et donc accessible à l'extérieur du module et le contraire (pas de mot-clé)rend la structure privée. Ainsi donc, tout éléments qui doit être visible et accessible à l'extérieur du module doit avoir les mots-clés "pub" . Mais attention, les bloc "impl" quant à eux ne peuvent en aucun cas être déclarés en accès public, car ce sont des blocs autonomes d'implémentations et seules leurs méthodes peuvent être déclarées en public pour y avoir accès.

    La solution proposée par le compilateur et @Pyramidev que vous avez adoptés n'est ni plus ni moins l'application de l'une des règles strictes d'utilisation des traits pour résoudre le problème. Car; les traits doivent être dans la porté du module faute de quoi; toutes les méthodes sont cachées. Donc tout élément des traits ne peut être utilisé que si le trait est dans la portée et le fait de déclarer "use personage::Move;" permets alors d'avoir un alias local donc, une porté pour tout le bloc ou module dans lequel se trouve la déclaration souhaiter.
    Celui qui peut, agit. Celui qui ne peut pas, enseigne.
    Il y a deux sortes de savants: les spécialistes, qui connaissent tout sur rien,
    et les philosophes, qui ne connaissent rien sur tout.
    George Bernard Shaw

  7. #7
    Membre habitué Avatar de bringer
    Homme Profil pro
    Enseignant
    Inscrit en
    Juin 2009
    Messages
    122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Juin 2009
    Messages : 122
    Points : 137
    Points
    137
    Par défaut
    Citation Envoyé par sambia39 Voir le message
    Ok; de mon points de vue, il faut partir du mots-clés "pub". Le mot-clé "pub" appliquer rend la structure ou l'élément sur lequel il est appliqué public et donc accessible à l'extérieur du module et le contraire (pas de mot-clé)rend la structure privée. Ainsi donc, tout éléments qui doit être visible et accessible à l'extérieur du module doit avoir les mots-clés "pub" . Mais attention, les bloc "impl" quant à eux ne peuvent en aucun cas être déclarés en accès public, car ce sont des blocs autonomes d'implémentations et seules leurs méthodes peuvent être déclarées en public pour y avoir accès.

    La solution proposée par le compilateur et @Pyramidev que vous avez adoptés n'est ni plus ni moins l'application de l'une des règles strictes d'utilisation des traits pour résoudre le problème. Car; les traits doivent être dans la porté du module faute de quoi; toutes les méthodes sont cachées. Donc tout élément des traits ne peut être utilisé que si le trait est dans la portée et le fait de déclarer "use personage::Move;" permets alors d'avoir un alias local donc, une porté pour tout le bloc ou module dans lequel se trouve la déclaration souhaiter.

    Bonjour sambia39,
    merci de ce complément de réponse bienvenu.

    Belle journée

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

Discussions similaires

  1. statut d'une table dans un module de donnee
    Par kewine dans le forum Bases de données
    Réponses: 3
    Dernier message: 17/11/2005, 03h56
  2. Comparaison de code dans plusieurs modules
    Par jbaudin dans le forum Access
    Réponses: 2
    Dernier message: 03/10/2005, 11h47
  3. Fonction retournant un recordset dans un module
    Par suspiria dans le forum Access
    Réponses: 3
    Dernier message: 29/09/2005, 15h46
  4. violation d'adresse dans le module 'bdert70.bpl'
    Par Magnus dans le forum Bases de données
    Réponses: 6
    Dernier message: 19/08/2005, 13h34
  5. [VB.NET] Appeler une sub public dans un module de form
    Par SergeF dans le forum Windows Forms
    Réponses: 3
    Dernier message: 01/06/2004, 13h08

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