2017-01-31 14 views
6

Obecnie używam tego wzoru:Jak mogę zwięźle połączyć wiele "wyników" różnych typów?

let a: Result<A, ParseError> = parseA(); 
let b: Result<B, ParseError> = parseB(); 
let c: Result<C, ParseError> = parseC(); 
a.and_then(|a| b.map(|b| (a, b))).and_then(|(a,b)| c.map(|c| { 
    // finally the crux of what I want to do 
    a.foo(b).bar(c) 
})) 

Czy jest bardziej zwięzły sposób określić a, b & c, takich jak Scala dla ekspresji?

+1

To nie jest dokładnie "łączenie wyników", jak próbujesz tutaj .. jednak ostatnio robię to - łączenie parsowania w iteracji przy sumowaniu wszystkiego razem (http: //play.integer32 .com /? gist = 9470f7e9f293852f7444c1017ae91fa9 & version = stable). Nie jestem pewien, czy jest to odpowiednie dla ciebie, zważywszy na znacznie trudniejsze określenie, które z nich nie powiodło się w tym scenariuszu (jeśli takowe są). –

+0

Podoba mi się. Chociaż to nie jest to, czego potrzebuję i uświadamia mi, że moje pytanie jest trochę mylące. Pójdę jeszcze napisać to. – Synesso

Odpowiedz

3

zwykle zawinąć wszystko w warstwach zamiast łączenia przez krotki:

let result = a.and_then(|a| { 
    b.and_then(|b| { 
     c.map(|c| { 
      a.foo(b).bar(c) 
     }) 
    }) 
}); 

Lub, w ostatnich wersjach rdza, można dokonać wyszukane użycie operatora ?:

let result = a.and_then(|a| { 
    a.foo(b?).bar(c?) 
}); 

Zamknięcia pozwalają zrobić to ładnie i bezpiecznie.

Oczywiście to nie działa, jeśli chcesz zapisać w zmiennej pośrednią Result.

+0

Czy też 'a? .foo (b?) .bar (c?)' Również nie działa? Lub nawet: 'parseA()? Foo (parseB()?) .bar (parseC()?)', Z tym ostatnim nie wykonującym 'parseB', jeśli' parseA' się nie powiedzie, i tak dalej. – user4815162342

+2

Tylko jeśli twoja funkcja zwraca "Wynik". Jeśli chcesz ręcznie przetworzyć to, to nie. Nawet jeśli zwrócisz 'Wynik', musisz zdecydować pomiędzy' Ok (a? Foo (b?)) 'A' a.i_then (| a | a.foo (b?)) ', Co w zależności od twojego prawdziwy kod może sprawić, że te ostatnie będą bardziej czytelne (w tym przypadku mamy tę sytuację często). –