Добавить контекст для нескольких результатов из внутренних вызовов - PullRequest
0 голосов
/ 08 апреля 2020

Как я могу выполнить некоторую постобработку для всей группы Result с? У меня был такой код:

fn stuff() -> Result<Quux, Error> {
    let a = foo().context("stuff() failed")?;
    let b = bar().context("stuff() failed")?;
    let c = baz().context("stuff() failed")?;
    quux(&a, &b, &c).context("stuff() failed")
}

Я хотел избавиться от повторяющихся вызовов к context() и отправился к версии, используя выражение немедленно вызванной функции (IIFE) :

fn stuff() -> Result<Quux, Error> {
    (|| {
        let a = foo()?;
        let b = bar()?;
        let c = baz()?;
        quux(&a, &b, &c)?
    })()
    .context("stuff() failed")
}

Есть ли лучший способ?

1 Ответ

3 голосов
/ 08 апреля 2020

На данный момент создание другой функции (или лямбды, как у вас) является практически единственным способом go.

Если вы действительно часто используете это, вы можете сделать его обобщенным c функция:

fn stuff() -> Result<Quux, Error> {
    with_error_context("stuff() failed", || {
        let a = foo()?;
        let b = bar()?;
        let c = baz()?;
        quux(&a, &b, &c)?
    })
}

fn with_error_context<T, E, F: FnOnce() -> Result<T, E>>(
    message: &str, f: F
) -> Result<T, E> {
    f().context(message)
}

Существует также нестабильная на данный момент функция try_blocks, которая позволит вам написать что-то вроде:

fn stuff() -> Result<Quux, Error> {
    try {
        let a = foo()?;
        let b = bar()?;
        let c = baz()?;
        quux(&a, &b, &c)?
    }.context("stuff() failed")
}
...