5
votes

A project I am working on has the following piece code:

val ftr1: Future[Try[(Date, String)]] = Future {
  if (someCondition) {
    // some code
    val amazonClient = Try[new com.amazonaws.services.s3.AmazonS3Client(...)]
    amazonClient.map { c => 
    // doing some stuff
    (new Date, "SomeString")
    }
  } else {
    // some code
    Failure(new Exception)
  }
}

Future.firstCompletedOf(Seq(ftr1, anotherFuture)) map {
  case t: Try[(Date, String)] => {
    t match {
      case Success(r) => //do some things
      case _ => //do some another things
  }
  case _ => //do some another things
}

So, during compiling I have following warning:

[warn] non-variable type argument java.util.Date in type pattern java.util.Date, String) is unchecked since it is eliminated by erasure

and

[warn] case t: (Date, String) => //do some things

And I actually do not understand, what these warnings mean and how can this code be refactored in order to get rid of these warnings?

1

1 Answers

1
votes

Try[+T] is an abstract class, one which you can't create an instance of.

There are two case classes which inherit from it, Success and Failure, which you should really be using.

The compiler is warning you that at compile time, type erasure is going to erase those types, thus matching on them isn't going to get you the results you want. More on that can be found in How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?

But, you can avoid all this completely if you simply match on Success and Failure to reduce the unnecessary nesting in your match:

val ftr1: Future[Try[(Date, String)]] = Future {
  if (someCondition) {
    // some code
    val amazonClient = Try { /* stuff */ }
    amazonClient.map { c => 
    // doing some stuff
    (new Date, "SomeString")
  } else Failure(new Exception)
}

Future.firstCompletedOf(Seq(ftr1, anotherFuture)) map {
   case Success((date, myString)) => /* do stuff */
   case Failure(e) => log(e)
}