2013-07-25 13 views
21

için de filtreli. Filtreyi nasıl halledebilirim/eğer gelecek vadeleri içeren bir anlayış için?Scala Gelecek Ben onay <code>if(i == 2)</code> başarısız olduğunda sonuç <code>Future(Test2)</code> istiyorum ben istisna <code>java.util.NoSuchElementException: Future.filter predicate is not satisfied</code></p> <p>olsun Aşağıdaki örnekte anlama

Scala REPL'de çalışan basitleştirilmiş bir örnek aşağıdadır.

Kodu:

import scala.concurrent.Future 
import scala.util.{ Try, Success, Failure } 
import scala.concurrent.ExecutionContext.Implicits.global 

val f1 = Future(1) 
val f2 = for { 
    i <- f1 
    if(i == 2) 
} yield "Test1" 
f2.recover{ case _ => "Test2" } 
f2.value 

cevap

11

, sen i == 2 göre filtreleme yapıyorsunuz. f1 değeri iki olmadığından, Success değil, bunun yerine bir Failure vermeyecektir. Hata mesajınız size bildirdiği için filtrenin yüklemi tatmin edilmedi. Ancak, f2.recover yeni bir Future döndürür. f2 değeri değiştirilmez. Hala Failure'u saklar. f2.value'u aradığınızda hata iletisini almanızın nedeni budur.

Düşünebildiğim tek alternatif, for-comprehensionhere gösterildiği gibi kullanıyor olabilir.

val f2 = for (i <- f1) yield { 
    if (i == 2) "Test1" 
    else "Test2" 
} 
f2.value 

Bu f3.value yapar.NEWLINEBu olarak Some(Success(Test2)) dönecektir.

+0

Ancak, "i <- f1" başarısız olması nedeniyle f2 başarısız olursa, sonuç "Test2" olmayacaktır, ancak yine de bir Hata olmayacaktır. –

8

Tabii ki tek bir çözümde kendim çözdüm. Belki daha iyi, daha akılcı çözümler var? senin for-comprehension yılında

import scala.concurrent.Future 
import scala.util.{ Try, Success, Failure } 
import scala.concurrent.ExecutionContext.Implicits.global 

val f1 = Future(1) 
val f2 = for { 
    i <- f1 
    if(i == 2) 
} yield "Test1" 
val f3 = f2.recover{ case _ => "Test2" } 
// OR val f3 = f2.fallbackTo(Future("Test2")) 
f3.value 
+1

O da docs belirtilen: http://docs.scala-lang.org/overviews/core/futures.html#functional_composition_and_forcomprehensions hayır ikinci bir bakış attığımda. – Magnus

+1

Ben burada 'kurtarmak' kullanarak düşünüyorum. Kurtarmanızın yalnızca filtre yüklemesine dayalı kural dışı durum için geçerli olmasını istiyorsanız, 'case _' ifadesini 'case ex: NoSuchElementException', 'NoSuchElementException' java.util'den geliyor. – cmbaxter

+0

Jürgen: Bu altı aylık bir soru, yukarıdaki kod bir REPL oturumundan çıkarılan bir örnekti, bu yüzden netliğe yöneldi. Yorum yapmaktansa, Scala'daki ifadeleri parantez içine alabilirsin? Katkının ne olduğunu görmemek. – Magnus

27

Bu benim görüşüme göre daha idiyic bir çözümdür. Bu yükleme işlevi, bir Future[Unit] veya istisnayı içeren başarısız bir gelecek oluşturur. Örneğiniz için bu, Success("Test1") veya Failure(Exception("Test2")) ile sonuçlanacaktır. Bu "Test1" ve "Test2" den biraz farklıdır, ancak bu sözdizimini daha kullanışlı buluyorum.

def predicate(condition: Boolean)(fail: Exception): Future[Unit] = 
    if (condition) Future(()) else Future.failed(fail) 

Böyle kullanabilirsiniz:

val f2 = for { 
    i <- f1 
    _ <- predicate(i == 2)(new Exception("Test2")) 
    j <- f3 // f3 will only run if the predicate is true 
} yield "Test1" 
+1

Bu çok yararlı bir öneriydi. Teşekkürler! – Tommi

+0

Çok açık, teşekkürler! – Artemis

İlgili konular