Какой будет подпись функции, возвращающей общую структуру? - PullRequest
1 голос
/ 05 июля 2019

Я проходил через ящик syslog, и из своей функции я хотел вернуть объект логгера, который, как мне кажется, имеет общую структуру syslog::Logger. Большая часть приведенного ниже фрагмента взята из документации к ящику, за исключением возвратной части и unwrap ().

extern crate syslog;
use syslog::{Facility, Error, Formatter3164};

pub fn get_logger() -> syslog::Logger{
    let formatter = Formatter3164 {
        facility: Facility::LOG_USER,
        hostname: None,
        process: "myprogram".into(),
        pid: 0,
    };
    syslog::unix(formatter).unwrap()
}

Однако я вижу

pub fn get_logger() -> syslog::Logger{
                       ^^^^^^^^^^^^^^ expected 3 type arguments

Подпись syslog::Logger struct

pub struct Logger<Backend: Write, T, Formatter: LogFormat<T>>

и подпись syslog::unix является

pub fn unix<U: Display, F: Clone+LogFormat<U>>(formatter: F) -> Result<Logger<LoggerBackend, U, F>> {

, где Display - это std::fmt::Display, а LogFormat - это черта, определенная в ящике syslog со следующим определением.

pub trait LogFormat<T> {
  fn format<W: Write>(&self, w: &mut W, severity: Severity, message: T)   -> Result<()>;

  fn emerg<W: Write>(&mut self, w: &mut W, message: T)   -> Result<()> {
    self.format(w, Severity::LOG_EMERG, message)
  }

  fn alert<W: Write>(&mut self, w: &mut W, message: T)   -> Result<()> {
    self.format(w, Severity::LOG_ALERT, message)
  }

  fn crit<W: Write>(&mut self, w: &mut W, message: T)    -> Result<()> {
    self.format(w, Severity::LOG_CRIT, message)
  }

  fn err<W: Write>(&mut self, w: &mut W, message: T)     -> Result<()> {
    self.format(w, Severity::LOG_ERR, message)
  }

  fn warning<W: Write>(&mut self, w: &mut W, message: T) -> Result<()> {
    self.format(w, Severity::LOG_WARNING, message)
  }

  fn notice<W: Write>(&mut self, w: &mut W, message: T)  -> Result<()> {
    self.format(w, Severity::LOG_NOTICE, message)
  }

  fn info<W: Write>(&mut self, w: &mut W, message: T)    -> Result<()> {
    self.format(w, Severity::LOG_INFO, message)
  }

  fn debug<W: Write>(&mut self, w: &mut W, message: T)   -> Result<()> {
    self.format(w, Severity::LOG_DEBUG, message)
  }
}

Это общая структура, так что бы я мог вернуть сигнатуру типа, если я хочу вернуть объект регистратора из моей функции?

1 Ответ

3 голосов
/ 05 июля 2019

Единственный необязательный параметр здесь - T. Это тип сообщения, которое вы хотите, когда вы входите в систему. Например. в приведенном ниже примере тип сообщения журнала - &str:

let mut logger = get_logger();

logger.info("This is a log message");

Вы можете выбрать тип внутри get_logger и поставить его в своей подписи, или сделать get_logger универсальным, и сделать так, чтобы сайт вызова принимал решение. Первый подход выглядит так:

extern crate syslog;
use syslog::{Facility, Error, Formatter3164, LoggerBackend};

fn get_logger<'a>() -> syslog::Logger<LoggerBackend, &'a str, Formatter3164>{
    let formatter = Formatter3164 {
        facility: Facility::LOG_USER,
        hostname: None,
        process: "myprogram".into(),
        pid: 0,
    };
    syslog::unix(formatter).unwrap()
}

pub fn main(){
  let mut logger = get_logger();

  logger.info("This is a log message");
}

И общий подход выглядит следующим образом.

extern crate syslog;
use syslog::{Facility, Error, Formatter3164, LoggerBackend};

pub fn get_logger<T: std::fmt::Display>() -> syslog::Logger<LoggerBackend, T, Formatter3164>{
    let formatter = Formatter3164 {
        facility: Facility::LOG_USER,
        hostname: None,
        process: "myprogram".into(),
        pid: 0,
    };
    syslog::unix(formatter).unwrap()
}

pub fn main(){
  let mut logger = get_logger();

  logger.info("This is a log message");
}
...