Вы можете сделать свой Logger
generi c без указания параметров generi c на call сайтах:
use std::fmt::Debug;
struct DBCon;
struct Logger<'a, T: Debug + Clone> {
con: &'a DBCon,
err: T,
}
impl<'a, T: Debug + Clone> Logger<'a, T> {
pub fn new (con: &'a DBCon, err: T) -> Self {
Logger { con, err }
}
pub fn log (self) {
eprintln!("{:?}", self.err.clone())
// Send self.err to database
}
// Additional log methods
}
fn main() {
let con = DBCon;
Logger::new (&con, "err").log();
Logger::new (&con, "err".to_owned()).log();
// Logger::new (&con, some_other_value_that_impl_Debug_and_Clone).log();
}
Playground
На сайтах вызовов (в примере с функцией main
) компилятор может автоматически угадывать типы, поэтому пользователям не нужно их печатать.
Также обратите внимание, что я использовал Self
в качестве типа возврата для метода Logger::new
. Это эквивалентно типу full , который я сейчас реализую, поэтому в данном случае Self
является псевдонимом для Logger<'a, T>
. С таким же успехом я мог бы написать: pub fn new (con: &'a DBCon, err: T) -> Logger<'a, T>
, но не pub fn new (con: &'a DBCon, err: T) -> Logger
, потому что Logger
сам по себе является неполным типом, без параметров generi c, и компилятор не будет выводить типы в прототипах функций.