我的代码大量使用Akka和无类型的actor。
典型逻辑的示例如下:
val myFuture: Future[Any] = akka.pattern.AskSupport.ask(myActorRef, myMessage)
val completedLogic: Future[Unit] = myFuture.map(myFunction)
然后myFunction包含一个强类型签名,如下所示:
def myFunction(): (Option[MyStronglyTypedClass]) => Unit = {
(myOption: Option[MyStronglyTypedClass]) => myOption foreach (myObject => // do some logic
}
我知道myFuture将始终包含此特定actor的MyStronglyTypedClass 或null 的实例。我也会知道其他演员/未来/功能组合。
当我想要创建从Future[Any]
到Option[MyStronglyTypedClass]
或Option[MyOtherStronglyTypedClass]
隐式转换只会在创建Option
之前进行空检查和另一条逻辑如何执行从Any到子类型的隐式转换,或者甚至可能?
答案 0 :(得分:3)
您应该转换为Future[Option[MyStronglyTypedClass]]
:
def asMyStronglyTypedClass(x: Any): Option[MyStronglyTypedClass] = x match {
case null => None
case ...
}
// this will fail if myFuture fails or asMyStronglyTypedClass throws
val typedFuture = myFuture.map(asMyStronglyTypedClass)
用你的未来做你想做的事。 E.g。
typedFuture.onSuccess(myFunction)
编辑:我想你已经有了map
。在这种情况下,问题是您不需要将Future[Any]
转换为Option
,而是将其结果转换为Any
)。你可以写例如myFuture.map(asMyStronglyTypedClass).map(myFunction)
或myFuture.map(x => myFunction(asMyStronglyTypedClass(x)))
。您也可以隐式asMyStronglyTypedClass
并写myFuture.map(x => myFunction(x))
。我仍然认为这不是一个好主意,因为它可以应用到不期望的地方。
如果你真的想写myFuture.map(myFunction)
,你需要一个不同的隐式转换来让编译器理解:
implicit def contraMap(f: Option[MyStronglyTypedClass] => Unit): Any => Unit =
x => f(asMyStronglyTypedClass(x))
当然,如评论中所述,这些可以在您的类型上使用。
答案 1 :(得分:1)
从Any转换为其他东西是你永远不应该做的事情,因为它有效地关闭了Scala的类型系统。可以使用
以安全的方式转换未来类型myFuture.mapTo[Option[MyStronglyTypedClass]]