Traits are similar to interfaces:
Traits are Rust’s sole notion of interface.
An interface is meant to document available methods, to have an interface with private methods makes no sense. Correspondingly, in Rust you can’t have different levels of visibility in one trait. If you can see the trait, you can always see all of it. However, Rust traits are subtly different from interfaces: they combine declarations and implementations. I see how it would be intuitive to have a trait with some private functions.
For some time it was possible to split a trait into a public and private part. You would have two traits, one containing your public interface, the other with your private functionality, but this is being removed in newer versions of Rust.
The current workaround is still splitting the trait, but the private part must now be represented by a public trait within a private module. To explain this, here is some sample code:
// this module contains a public trait Inc, to increment a value
// and it implements it by using a private trait Add
mod my_math {
pub struct Val {
pub val: i32,
}
// this is necessary to encapsulate the private trait
// the module is private, so the trait is not exported
mod private_parts {
pub trait Add {
fn add(&mut self, i32);
}
}
// in the following code, we have to use adequate namespacing
impl private_parts::Add for Val {
fn add(&mut self, other: i32) {
self.val += other;
}
}
pub trait Inc: private_parts::Add {
fn inc(&mut self);
}
impl Inc for Val {
fn inc(&mut self) {
use my_math::private_parts::Add;
self.add(1)
}
}
}
fn main() {
use my_math::Inc;
let mut b = my_math::Val { val: 3 };
println!("value: {}", b.val);
b.inc();
println!("value: {}", b.val);
}