Public API
- Rust course
- Intermediate
- Lesson 26/115
- 6 min
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
fn main() {
// buraya yaz
}Sample 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());
}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
pub fn ad(&self) -> ____ {
&self.ad
}
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 |