Rust
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.
Exercise 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.
Show example solution
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());
}
Test yourself
-
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
- Yes
Show answer
No; a struct with private fields can't be built from outside, a constructor is needed — This is how invariants are protected: the only way to create a Kitap is through the constructor.
-
Read method
pub fn ad(&self) -> ____ {
&self.ad
}
Show answer
pub fn ad(&self) -> &str {
&self.ad
}
-
Visibility and scope
- pub
- Everywhere
- pub(crate)
- Same crate
- pub(super)
- Parent module
- (none)
- Module only
Next lesson: Generic structure