Scala Generics vs Any

时间:2015-07-30 18:48:12

标签: scala generics casting

在我正在编写的代码中,我有一个名为SuccessMessage的类,其中包含字段actorType(枚举)和有效负载。我不确定制造有效载荷的类型。

如果我创建了Any类型的有效负载,我必须做很多看起来很糟糕的instanceOf类型转换,以便稍后在我的代码中处理更具体的实现。

如果我使用泛型,并使T类型的有效负载,我的其他类也必须包括类型T.例如,在我的高级特征称为Commander,我有一个名为handleSuccess的方法,它接受SuccessMessage ,它必须能够接收泛型类型T的成功消息,迫使我的指挥官也是通用类型T。

我不确定我是否必须在这两个较小的邪恶之间进行选择,或者是否有更好的方法。我必须包括一些生成有效负载的方法,因为Success Message需要不同类型的有效负载。

编辑: 泛型还有一个问题。 Commander必须能够处理许多不同类型的SuccessMessages,因此如果在handleSuccess中需要SuccessMessage [T],强制Commander成为Commander [T],那么Commander将无法处理不同类型的成功消息(我想,不是100%肯定)。

编辑2: 这是一个短暂的指挥官:

trait Commander {
  def handleSuccess(message: SuccessMessage){
     //based on SuccessMessage.ActorType, do different stuff
  }

class SuccessMessage(val actorType: ActorType, val payload: Option[Any])
class SuccessMessage(val actorType: ActorType, val payload: Option[T])

编辑3:这是对更好地解释问题的工作流程的描述。

  • 指挥官将消息发送给Poller
    • Poller将SuccessMessage(self,List [String])发送给Commander
  • Commander将List [String]发送给处理器
    • 处理器将SuccessMessage(self,File)发送给Commander
  • Commander将文件发送给上传器
    • Uploader将SuccessMessage(self,Boolean)发送给Commander
  • 等等。

因此,我们需要SuccessMessage采用不同的类型。

1 个答案:

答案 0 :(得分:2)

除非T具有允许编译器假定其行为的某些类型的某些类型边界,否则您必须将T的实例强制转换为某种具体类型,以便将它们用于任何明确的目的。 (与Any基本相同的问题)

您可能希望查看类型类。然后,您可以为每种类型定义某种处理程序,并使用隐式类型类实例将传入的有效内容与处理程序进行匹配。 (见https://github.com/mpilquist/simulacrum库)

编辑:此处的示例 - > https://gist.github.com/phaistos/51f0405a2f25812a5780 基本上你最终会得到一个类型类:

@typeclass trait CommanderHandler[A] {
   def handle(payload: A): Unit
}

然后为每个要用作有效负载的类型创建一个实例:

implicit val handlerInt: CommanderHandler[Int] = new CommanderHandler[Int] {
  def handle(payload: Int) { /* use the payload here */ }
}

然后你可以创建一个这样的函数来处理它们:

def consumePayload[T](t: T)(implicit h: CommanderHandler[T]) {
  h.handle(t)
}

您为给定类型创建的隐式必须在consumePayload的呼叫站点上可用。基本上你只是将每个类型的处理程序包装在一个漂亮的小包中。

这是迄今为止我发现的最好的模式。希望能帮助到你。如果你使用它,请确保你阅读了simulacrum的文档,你需要在创建类型类之后进行一些导入才能使它工作。

编辑:作为替代方案,您还可以通过无形的方式查看多态方法:https://github.com/milessabin/shapeless/wiki/Feature-overview:-shapeless-2.0.0#polymorphic-function-values