Scala:比较类型

时间:2012-11-07 18:06:52

标签: scala

我想定义一个可以比较两种类型的函数。我定义了两个不同的类:

abstract class Task
case class DefinedTask(id: Long) extends Task
case class EmptyTask() extends Task  

然后我有一个函数返回Task类型的对象,可以是DefinedTaskEmptyTask

现在,我要做的是拥有一个功能,可以识别此对象是DefinedTask还是仅EmptyTask。问题很简单,我会使用模式匹配。但我想概括它,因为多个类使用此Defined/Empty模式。

到目前为止我尝试的是:

def makeReturned[T: Manifest, U: Manifest](obj: T)(u: U)(f: T => Value) = 
   if(manifest[U] equals manifest[T]) f(obj) else
     throw new IllegalArgumentException()
}
//call to it
makeReturned(task)(DefinedTask)(makeTask)

U始终为DefinedTaskT可以是DefinedTask or EmptyTask,但会以Task的形式返回。

manifest[U].erasure.toString //"class DefinedTask$"
manifest[T].erasure.toString //"class Task"  

从编译器的立场来看,这是正确的,但它并不适合我。所以,我的问题是我怎么能以一种能给我想要的方式来比较它们呢?

2 个答案:

答案 0 :(得分:1)

看起来你想要运行时,而不是编译时检查。所以我认为你的意思是

def makeReturned[U <: Task, T <: Task](obj: T)(u: U)(f: T => Value) = {
  if (obj.getClass.isInstance(u.getClass)) f(obj)
  else throw new IllegalArgumentException
}

或类似的东西。查看java.lang.Class上的方法,然后选择符合您需要的方法。

答案 1 :(得分:1)

  1. 您的代码中存在一些错误:
    • 您应该abstract class Task密封以进行详尽的模式匹配
    • 不推荐使用空案例类。编译器应该已经警告过你。 case object EmptyTask extends Task将是正确的选择
  2. 案例类和案例对象都扩展了特征Product。您可以使用以下任一方法检查产品是否为空:
    • task.productArity == 0
    • task.productIterator.isEmpty
  3. 我认为你在重新解决问题方面要好得多。为什么不使用标准Option并将简单case class Task(id: Int)的实例包含在其中?这可能是您所有其他类似实体的一般方法。