Çözüm

pub trait Logger {
    /// Belirtilen ayrıntı seviyesinde bir mesaj kaydedin.
    fn log(&self, verbosity: u8, message: &str);
}

struct StderrLogger;

impl Logger for StderrLogger {
    fn log(&self, verbosity: u8, message: &str) {
        eprintln!("ayrıntı seviyesi={verbosity}: {message}");
    }
}

/// Yalnızca bir filtreleme koşuluyla eşleşen günlük mesajlarını kaydet.
struct Filter<L, P> {
    inner: L,
    predicate: P,
}

impl<L, P> Filter<L, P>
where
    L: Logger,
    P: Fn(u8, &str) -> bool,
{
    fn new(inner: L, predicate: P) -> Self {
        Self { inner, predicate }
    }
}
impl<L, P> Logger for Filter<L, P>
where
    L: Logger,
    P: Fn(u8, &str) -> bool,
{
    fn log(&self, verbosity: u8, message: &str) {
        if (self.predicate)(verbosity, message) {
            self.inner.log(verbosity, message);
        }
    }
}

fn main() {
    let logger = Filter::new(StderrLogger, |_verbosity, msg| msg.contains("berbat"));
    logger.log(5, "Bilginiz Olsun");
    logger.log(1, "berbat, bir şeyler ters gitti");
    logger.log(2, "eyvah");
}
  • İlk Filter impl bloğundaki P: Fn(u8, &str) -> bool sınırının kesinlikle gerekli olmadığını, ancak new çağrılırken tür çıkarımına (type inference) yardımcı olduğunu unutmayın. Onu kaldırmayı gösterin ve derleyicinin şimdi new’e geçirilen çevreleyici (closure) için tür ek açıklamalarına (type annotations) nasıl ihtiyaç duyduğunu gösterin.