Как избежать дублирования кода для функции, которая использует необязательный параметр сообщения? - PullRequest
0 голосов
/ 18 марта 2020

Я хочу написать свою собственную функцию assert, которая при желании может иметь сообщение:

fn foo(msg: Option<&str>) {
    if let Some(m) = msg {
        panic!("{} - Something went wrong: {}", m, "additional info");
    } else {
        panic!("Something went wrong: {}", "additional info")
    }
}

Как избежать подобного дублирования кода? Как избежать многократного (пере) выделения строк сообщения?

Ответы [ 2 ]

4 голосов
/ 19 марта 2020

Я часто использую маленькую обертку, подобную этой:

struct OrEmptyS<T>(Option<T>);

impl<'a, T: std::fmt::Display> std::fmt::Display for OrEmptyS<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
        if let Some(v) = &self.0 {
            v.fmt(f)
        } else {
            Ok(())
        }
    }
}

// Extension trait to add methods on `Option`
trait OrEmpty<T> {
    fn or_empty(&self) -> OrEmptyS<&T>;
    fn empty_or<'a, U: ?Sized>(&'a self, alt: &'a U) -> OrEmptyS<&'a U>;
}

impl<T> OrEmpty<T> for Option<T> {
    fn or_empty(&self) -> OrEmptyS<&T> {
        OrEmptyS(self.as_ref())
    }

    fn empty_or<'a, U: ?Sized>(&'a self, alt: &'a U) -> OrEmptyS<&'a U> {
        OrEmptyS(self.as_ref().map(|_| alt))
    }
}

, которую вы можете использовать как

fn foo(msg: Option<&str>) {
    panic!(
        "{}{}Something went wrong: {}",
        msg.or_empty(),
        msg.empty_or(" - "),
        "additional info"
    );
}

( Постоянная ссылка на игровую площадку )

2 голосов
/ 18 марта 2020

Используйте пустые строки, когда вы не печатаете.

fn foo(msg: Option<&str>) {
    panic!("{}{}Something went wrong: {}", 
            { if let Some(m) = msg { m } else { "" } },
            { if let Some(_m) = msg { " - " } else { "" } },
            "additional info");
}

Что после rustfmt выглядит так:

fn foo(msg: Option<&str>) {
    panic!(
        "{}{}Something went wrong: {}",
        {
            if let Some(m) = msg {
                m
            } else {
                ""
            }
        },
        {
            if let Some(_m) = msg {
                " - "
            } else {
                ""
            }
        },
        "additional info"
    );
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...