Scala:隐式转换为通用子类型

时间:2014-02-25 03:12:32

标签: scala akka

我的代码大量使用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到子类型的隐式转换,或者甚至可能?

2 个答案:

答案 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]]