我最近开始使用Akka / Scala编码,我遇到了以下问题:
在范围内进行隐式转换,例如:
implicit def convertTypeAtoTypeX(a: TypeA): TypeX =
TypeX() // just some kinda conversion
这有效:
returnsAFuture.mapTo[TypeX].map { x => ... }
但这不是:
returnsAFuture.mapTo[TypeX].onComplete { ... }
后者因类型转换异常而失败。 (即TypeA不能转换为TypeX)
非常困惑。为什么?我怀疑它与Try有关,但我不知道要么猜出任何答案:(
谢谢!
答案 0 :(得分:7)
来自doc:
def mapTo[S](implicit tag: ClassTag[S]): Future[S]
Creates a new Future[S] which is completed with this Future's result if that conforms to S's erased type or a ClassCastException otherwise.
此函数可能仅用于在某些继承关系中的对象之间进行转换。它不期望任何隐含证据从[T]转换为[S](它甚至不知道T!)
此功能用于Akka,在那里你问演员并收到回复Future [Any]。但是你知道一个Actor会返回你的String,所以你可以安全地编写actor.ask(...).mapTo[String]
,这样就可以了,因为Any可以被渲染到一切。这里没有使用隐式转换。
现在你说你的第一个例子有效。但是这条线甚至没有计算,因为你从未要求过结果。可视化scala编译器说:你只做一个地图(从类型X改为Y型)这个未来的结果但从未真正使用它,所以如果你不关心自己,为什么还要执行呢?
如果您在第一行中的地图后添加了onComplete,则会看到相同的ClassCastException。
现在可能是你想要的,但这很有趣:
returnsAFuture.map { x => x.fieldOnlyInTypeX }
如果你使用“x”就像它是TypeX类型一样,一切都会正常工作。 Scala编译器将隐式转换应用于“x”以将其转换为TypeX。这可能不是你想要的,因为“x”仍然是TypeA类型,并且在地图中每次使用时都是隐式转换的。
〜Krzysiek