Menu
Coddy logo textTech

Champs privés

Fait partie de la section Object Oriented Programming du Journey Rust de Coddy — leçon 10 sur 61.

Dans la leçon précédente, vous avez tout rendu public — la struct, ses champs et ses méthodes. Mais une véritable encapsulation signifie contrôler comment vos données peuvent être consultées. En Rust, vous pouvez rendre une struct publique tout en gardant ses champs privés.

Considérez un Wallet qui ne devrait jamais avoir un solde négatif. Si le champ est public, n'importe qui pourrait lui attribuer n'importe quelle valeur :

// wallet.rs
pub struct Wallet {
    balance: f64,  // Pas de pub = privé !
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Wallet { balance: initial }
    }
}

Remarquez que Wallet est public, mais que balance n'a pas de mot-clé pub. Cela signifie que le code à l'extérieur du module peut créer un Wallet en utilisant le constructeur, mais ne peut pas lire ou modifier directement le champ balance :

// main.rs
mod wallet;
use wallet::Wallet;

fn main() {
    let w = Wallet::new(100.0);
    // println!("{}", w.balance);  // Erreur ! le champ est privé
    // w.balance = -50.0;          // Erreur ! impossible d'accéder au champ privé
}

C'est le fondement de l'encapsulation : la struct contrôle ses propres données. Le code externe doit passer par les méthodes que vous fournissez, ce qui signifie que vous pouvez ajouter de la validation, de la journalisation ou toute autre logique. Les données restent protégées contre les états invalides.

Dans les prochaines leçons, vous apprendrez comment fournir un accès contrôlé à ces données privées via des méthodes getter et setter.

challenge icon

Défi

Facile

Construisons un système de capteur de température qui démontre l'encapsulation en gardant les données sensibles protégées à l'intérieur d'un module.

Vous allez créer deux fichiers pour organiser votre code :

  • sensor.rs : Définissez une structure TemperatureSensor avec deux champs : location (String) et reading (f64). La structure doit être publique pour pouvoir être utilisée depuis d'autres fichiers, mais gardez les deux champs privés — le code externe ne doit pas pouvoir accéder directement aux données du capteur ni les modifier. Ajoutez un constructeur public new qui prend un nom de lieu et un relevé de température initial.
  • main.rs : Importez votre module de capteur et créez un TemperatureSensor en utilisant le constructeur. Comme les champs sont privés, vous ne pourrez pas les afficher directement — à la place, affichez un message de confirmation indiquant que le capteur a été créé avec succès.

Ce défi se concentre sur le concept central des champs privés : la structure est accessible, mais ses données internes sont protégées. Le code externe ne peut interagir avec le capteur qu'à travers les méthodes que vous fournissez (dans ce cas, seulement le constructeur).

Votre sortie doit suivre ce format exact :

Sensor created for: {location}

Pour accéder au lieu pour l'affichage, vous devrez faire en sorte que votre fonction new affiche ce message avant de retourner le capteur, puisque le champ lui-même est privé.

Par exemple, si vous créez un capteur avec le lieu "Kitchen" et le relevé 22.5, la sortie sera :

Sensor created for: Kitchen

Vous recevrez deux entrées : le nom du lieu et le relevé de température initial.

Aide-mémoire

En Rust, vous pouvez rendre une structure publique tout en gardant ses champs privés pour réaliser l'encapsulation. Cela empêche le code externe d'accéder directement aux données internes ou de les modifier.

Pour rendre un champ privé, il suffit d'omettre le mot-clé pub :

pub struct Wallet {
    balance: f64,  // Pas de pub = champ privé
}

impl Wallet {
    pub fn new(initial: f64) -> Wallet {
        Wallet { balance: initial }
    }
}

Dans cet exemple, Wallet est public (peut être utilisé en dehors du module), mais balance est privé (ne peut pas être accédé directement de l'extérieur).

Le code externe peut créer des instances en utilisant des constructeurs publics mais ne peut pas lire ou modifier les champs privés :

mod wallet;
use wallet::Wallet;

fn main() {
    let w = Wallet::new(100.0);
    // println!("{}", w.balance);  // Erreur ! le champ est privé
    // w.balance = -50.0;          // Erreur ! impossible d'accéder au champ privé
}

Cette encapsulation garantit que la structure contrôle ses propres données, et le code externe doit utiliser les méthodes que vous fournissez pour interagir avec elle.

Essayez vous-même

mod sensor;

use sensor::TemperatureSensor;

fn main() {
    // Lire l'entrée
    let mut location = String::new();
    std::io::stdin().read_line(&mut location).expect("Failed to read line");
    let location = location.trim().to_string();
    
    let mut reading_str = String::new();
    std::io::stdin().read_line(&mut reading_str).expect("Failed to read line");
    let reading: f64 = reading_str.trim().parse().expect("Failed to parse reading");
    
    // TODO: Créer un TemperatureSensor en utilisant le constructeur
    // La fonction new s'occupera d'afficher le message de confirmation
    
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming