Using mapTo with futures in Akka / Scala

I recently started coding with Akka / Scala, and I ran into the following problem:

With implicit conversion to scope, for example:

implicit def convertTypeAtoTypeX(a: TypeA): TypeX = TypeX() // just some kinda conversion 

It works:

 returnsAFuture.mapTo[TypeX].map { x => ... } 

But this is not so:

 returnsAFuture.mapTo[TypeX].onComplete { ... } 

The latter ends with the exception of type cast. (i.e. TypeA cannot be passed to TypeX)

Very vaguely. What for? I suspect this has something to do with Try, but I don't know enough to either guess any answer :(

Thanks!

+6
source share
1 answer

From the doc:

 def mapTo[S](implicit tag: ClassTag[S]): Future[S] Creates a new Future[S] which is completed with this Future result if that conforms to S erased type or a ClassCastException otherwise. 

This function can only be used for casting between objects that are in some inheritance. He does not expect any implicit evidence to convert from [T] to [S] (he does not even know about T!)

This function is used, for example, in Acca, where you ask the actor and get Future [Any] in response. But you know that an actor will return a string to you so that you can write actor.ask(...).mapTo[String] , and this will work, because anyone can be cast to anything. Implicit conversions are not used here.

Now you say that your first example is working. But this line is not even calculated, since you never ask for the result. For clarity, the Scala compiler says: well, you only make a map (switching from type X to type Y) for the result of this future, but in fact you never use it, so why do it at all if you don’t care About Me?

If you add onComplete after your map in the first line, you will see the same ClassCastException.

This is probably what you want now, but it is interesting:

 returnsAFuture.map { x => x.fieldOnlyInTypeX } 

if you use "x" as if it were a TypeX type, everything will work fine. The Scala compiler will apply the implicit conversion to "x" to convert it to TypeX. This is probably not what you want, because the "x" is still of type TypeA and will be implicitly converted every time it is used in the map.

~ Krzysiek

+8
source

Source: https://habr.com/ru/post/984347/


All Articles