Каков рекомендуемый способ создания побочных эффектов в потоке управления с помощью Result? - PullRequest
0 голосов
/ 07 апреля 2019

Result::and_then() отлично подходит для составления потока управления.

fn some_fn() -> Result<String, Error> {
    Ok("Yay".to_string())
}
some_fn()
    .and_then(|value| some_other_fn())
    .and_then(|some_other_value| /* ... */)

Иногда мы хотим создать побочный эффект и по-прежнему распространять излучаемое значение. Допустим, мы хотим напечатать значение в момент его получения:

some_fn()
    .and_then(|value| {
        println!("{}", &value);
        some_other_fn()
    })
    .and_then(|some_other_value| /* ... */)

Есть ли лучший способ сделать это? Что-то вроде оператора tap() Reactive Extensions было бы замечательно.

1 Ответ

2 голосов
/ 07 апреля 2019

map и and_then подходят для случаев, когда вы хотите преобразовать значение.Использование match или if let подходит для побочных эффектов:

let r = some_fn();

if let Ok(v) = &r {
    println!("{}", v);
}

r.and_then(|_| some_other_fn())

См. Также:

Предполагая , что вы заботитесь о побочных эффектах только тогда, когда Result равен Ok ...

Вы также можете создать расширение для добавления нужного метода к Result.Я бы посоветовал назвать это inspect, поскольку это имя параллельного метода для Iterator.

trait InspectExt<T> {
    fn inspect<F>(self, f: F) -> Self
    where
        F: FnOnce(&T);
}

impl<T, E> InspectExt<T> for Result<T, E> {
    fn inspect<F>(self, f: F) -> Self
    where
        F: FnOnce(&T),
    {
        if let Ok(v) = &self {
            f(v)
        }
        self
    }
}
some_fn()
    .inspect(|v| println!("{}", v))
    .and_then(|_| some_fn())

См. Также:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...