CodeBlanks Logo Icon CodeBlanks

Public API

Expose an API with pub.

Public API

Leaving fields open locks the library's internal structure to its users: renaming a field breaks everyone's code. The better way is to keep fields private and offer a constructor and read methods:

pub struct Kitap {
    ad: String,
    yazar: String,
    yil: u16,
}

impl Kitap {
    pub fn new(ad: &str, yazar: &str, yil: u16) -> Self { .. }
    pub fn ad(&self) -> &str { &self.ad }
    pub fn yil(&self) -> u16 { self.yil }
}

Now the constructor can, for example, check whether the year is valid, and the internal representation can change freely.

pub(crate)

Visibility can be fine-tuned: pub(crate) opens an item only within the same crate, pub(super) only to the parent module. It's used for helpers shared between the library's own modules but hidden from users:

pub(crate) fn normalize(s: &str) -> String {
    s.trim().to_lowercase()
}

Keeping things private is the most effective way to keep an API small and stable: everything you expose is a promise you must not break later.

Practice Encapsulated book

Inside mod kitaplik, define Kitap with private fields and write the methods pub fn new, pub fn ad and pub fn yil. Print the name and year of Kitap::new("Kürk Mantolu Madonna", "Sabahattin Ali", 1943) separated by a space.

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
mod kitaplik {
    pub struct Kitap {
        ad: String,
        yazar: String,
        yil: u16,
    }

    impl Kitap {
        pub fn new(ad: &str, yazar: &str, yil: u16) -> Self {
            Self {
                ad: ad.to_string(),
                yazar: yazar.to_string(),
                yil,
            }
        }
        pub fn ad(&self) -> &str {
            &self.ad
        }
        pub fn yil(&self) -> u16 {
            self.yil
        }
    }
}

use kitaplik::Kitap;

fn main() {
    let k = Kitap::new("Kürk Mantolu Madonna", "Sabahattin Ali", 1943);
    println!("{} {}", k.ad(), k.yil());
}

Expected output

Kürk Mantolu Madonna 1943

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 With private fields, can <code>Kitap { ad: .., yazar: .., yil: .. }</code> be written outside the module?

  • Only for reading
  • With unsafe
  • No; a struct with private fields can't be built from outside, a constructor is needed Correct answer
  • Yes

Explanation: This is how invariants are protected: the only way to create a Kitap is through the constructor.

2 Read method

Question
pub fn ad(&self) -> ____ {
    &self.ad
}
Answer
pub fn ad(&self) -> &str {
    &self.ad
}

Explanation: The getter gives the field as &str without copying.

3 Visibility and scope

Term Meaning
pub Everywhere
pub(crate) Same crate
pub(super) Parent module
(none) Module only

All lessons in Intermediate