I just started exploring how traits work, here is a code snippet:
use core::{fmt,fmt::Debug,fmt::Formatter};
/// Compiled expression which yields type T when evaluated.
pub trait CExp<T>
{
fn eval( &self, e: &mut EvalEnv ) -> T;
fn format( &self, f: &mut Formatter ) -> fmt::Result;
}
impl <T> Debug for dyn CExp<T>
{
fn fmt(&self, f: &mut Formatter) -> fmt::Result
{
self.format( f )
}
}
#[derive(Debug)]
pub struct Add<T>
{
left: Box<dyn CExp<T>>,
right: Box<dyn CExp<T>>
}
impl <T> CExp<T> for Add<T> where T: std::ops::Add<Output = T> + Debug
{
fn eval( &self, e: &mut EvalEnv ) -> T
{
self.left.eval( e ) + self.right.eval( e )
}
fn format( &self, f: &mut Formatter ) -> core::fmt::Result
{
self.fmt( f )
}
}
This works, and I can Debug print everything. Every struct I make which implements CExp has the same code for format. This is quite ok, but is there a trick to avoid repeating the "redundant" code for format over and over again?